کسٹم ویوز کسی بھی موبائل ایپلیکیشن کے منفرد انٹرفیس کی بنیاد ہیں۔ موبائل ایپلیکیشنز میں کسٹم ویوز آپ کو اپنی گرافکس، اینیمیشنز اور ایسے عناصر بنانے کی اجازت دیتی ہیں جو معیاری اجزاء میں دستیاب نہیں ہیں۔ Apple Developer، 2025 کے مطابق، iOS موبائل ڈیولپمنٹ میں drawRect کسٹم ڈرائنگ کا بنیادی طریقہ بنا ہوا ہے۔ Android پر، Canvas کے ساتھ onDraw وہی کردار ادا کرتا ہے، اور Flutter میں — CustomPainter۔
اہم نکات
کسٹم ویوز صارف کے طے کردہ انٹرفیس اجزاء ہیں جو منفرد گرافکس بنانے کے لیے معیاری ڈرائنگ اور پیمائش کے طریقوں کو اوور رائڈ کرتے ہیں۔ چارٹس، اینیمیشنز، ڈایاگرام، کسٹم چیٹ عناصر اور AR ماسک — موبائل ایپلیکیشنز میں کسٹم ویوز کے استعمال کے مخصوص منظرنامے ہیں۔ معیاری UI اجزاء (Button، TextView، Label) 80% کاموں کو کور کرتے ہیں، لیکن باقی 20% کے لیے موبائل ڈیولپمنٹ میں ڈرائنگ پر مکمل کنٹرول درکار ہوتا ہے۔ موبائل ڈیولپمنٹ میں ڈرائنگ ایک ایسی مہارت ہے جو جونیئر ڈیولپر کو سینئر سے ممتاز کرتی ہے۔
موبائل ایپلیکیشنز میں کسٹم ویوز منفرد 2D گرافکس، پیچیدہ اینیمیشنز، چارٹس اور ڈیٹا ویژولائزیشن کے لیے ضروری ہیں۔ اگر معیاری UIKit مطلوبہ عنصر فراہم نہیں کرتا — تو ایک کسٹم ویو بنایا جاتا ہے۔ موبائل ایپلیکیشنز میں، کسٹم ویوز پروگریس بارز، کسٹم بٹن، گریڈینٹ فلز، اینیمیٹڈ آئیکنز اور انگلی سے ڈرائنگ کینوس کے لیے استعمال ہوتی ہیں۔ زیادہ استعمال نہ کرنا ضروری ہے — سادہ اسٹائل کے لیے، Appearance API کے ذریعے معیاری اجزاء کو کنفیگر کرنا کافی ہے۔
iOS پر، کسٹم ویوز UIView سے وراثت حاصل کرکے اور drawRect طریقہ کو اوور رائڈ کرکے بنائی جاتی ہیں۔ drawRect پہلی رینڈرنگ پر اور ہر setNeedsDisplay() کال کے بعد کال کیا جاتا ہے۔ drawRect کے اندر، ڈیولپر UIGraphicsGetCurrentContext() کے ذریعے CGContext حاصل کرتا ہے — لائنوں، اشکال، گریڈینٹس اور متن کے لیے ایک کینوس۔ Core Graphics (Quartz 2D) ایک نچلی سطح کا CPU پر مبنی رینڈرنگ انجن ہے جو ہر پکسل پر مکمل کنٹرول دیتا ہے۔ UIBezierPath مختصر نحو کے ساتھ راستے بنانے کے لیے ایک آسان ریپر ہے۔
class CircleView: UIView {
private var fillColor: UIColor = .systemBlue
override func drawRect(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.setFillColor(fillColor.cgColor)
ctx.addEllipse(in: bounds.insetBy(dx: 4, dy: 4))
ctx.drawPath(using: .fill)
}
func updateColor(_ newColor: UIColor) {
fillColor = newColor
setNeedsDisplay()
}
}
Core Graphics تمام ڈرائنگ آپریشنز کے لیے CGContext — ایک کینوس فراہم کرتا ہے۔ CGGradient CGColorSpace (sRGB، Display P3) کے تعاون کے ساتھ لکیری اور شعاعی گریڈینٹس بناتا ہے۔ تبدیلیاں CGAffineTransform کے ذریعے انجام دی جاتی ہیں — گردش، پیمائش اور منتقلی کے لیے 3x3 میٹرکس۔ CGContextTranslateCTM، CGContextRotateCTM اور CGContextScaleCTM کوآرڈینیٹ سسٹم کو تبدیل کرتے ہیں۔ Core Graphics CPU پر چلتا ہے، لہٰذا پیچیدہ گرافکس پروسیسر کو لوڈ کر سکتے ہیں — GPU ایکسلریشن کے لیے Metal استعمال کریں۔
UIBezierPath CGPath کے اوپر ایک آبجیکٹ اورینٹڈ ریپر ہے۔ addArc(withCenter:radius:startAngle:endAngle:clockwise:) طریقہ قوسین اور دائرے بناتا ہے، addCurve Bézier منحنی خطوط بناتا ہے۔ راستے addClip کے ذریعے اتحاد، تقاطع اور تفریق کے آپریشنز کو سپورٹ کرتے ہیں۔ UIBezierPath کسٹم ماسک (maskView)، کلپنگ پاتھ اور پیچیدہ شکلیں — ستارے، دل، کسٹم آئیکنز کے لیے آسان ہے۔
Android پر، ایک کسٹم ویو onDraw(Canvas) کو اوور رائڈ کرکے View کو بڑھاتا ہے۔ Canvas میں موبائل ڈیولپمنٹ میں ڈرائنگ کے تمام طریقے شامل ہیں: drawCircle، drawRect، drawLine، drawText، drawBitmap، drawPath اور drawRoundRect۔ Paint پیرامیٹرز کنفیگر کرتا ہے — رنگ، لائن کی موٹائی، اسٹائل (FILL، STROKE، FILL_AND_STROKE)، اینٹی الیاسنگ (isAntiAlias) اور متن کا سائز۔ onDraw ہر invalidate() پر کال کیا جاتا ہے اور اس میں بھاری آپریشنز نہیں ہونے چاہئیں — تمام حسابات کیش ہو جاتے ہیں۔
class CustomCircleView(context: Context, attrs: AttributeSet?)
: View(context, attrs) {
private val paint = Paint().apply {
style = Paint.Style.FILL
color = Color.BLUE
isAntiAlias = true
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = minOf(cx, cy) - 4f
canvas.drawCircle(cx, cy, radius, paint)
}
}
Android پر Path، UIBezierPath کے مساوی ہے: addCircle، addRect، addOval، lineTo، cubicTo اور quadTo۔ PathMeasure راستے کی لمبائی اور کسی بھی نقطہ پر کوآرڈینیٹس کا حساب لگاتا ہے — کسی راستے کے ساتھ آبجیکٹ کی حرکت کو اینیمیٹ کرنے کے لیے مفید۔ اینیمیشنز کے لیے، کال بیک میں invalidate() کے ساتھ ValueAnimator استعمال کیا جاتا ہے۔ اینیمیٹر رنگ، رداس، مقام تبدیل کر سکتا ہے — کوئی بھی خاصیت جو ڈرائنگ کو متاثر کرتی ہے۔ Android پر کسٹم ویوز XML کے ذریعے اینیمیشن کے لیے StateListDrawable اور animated-vector کو بھی سپورٹ کرتی ہیں۔
Android پر گریڈینٹس Shader کے ذریعے سیٹ کیے جاتے ہیں — LinearGradient، RadialGradient اور SweepGradient۔ Shader کو paint.setShader(shader) کے ذریعے Paint کو تفویض کیا جاتا ہے۔ LinearGradient دو پوائنٹس کے درمیان اختیاری رنگین پوزیشنوں کے ساتھ ایک لکیری گریڈینٹ پیدا کرتا ہے۔ RadialGradient — مرکز سے کناروں تک شعاعی۔ SweepGradient — ایک مرکزی نقطہ کے گرد مخروطی۔ Shader.TileMode (CLAMP، REPEAT، MIRROR) علاقے کی حدود سے باہر رویے کی وضاحت کرتا ہے۔
Flutter CustomPainter استعمال کرتا ہے — paint(Canvas canvas, Size size) اور shouldRepaint طریقوں والی ایک کلاس۔ Flutter میں Canvas وہی طریقے فراہم کرتا ہے جو Android میں ہیں: drawCircle، drawRect، drawLine، drawPath، drawParagraph اور drawImage۔ Flutter میں Paint رنگ، موٹائی، اسٹائل اور اینٹی الیاسنگ کنفیگر کرتا ہے۔ Flutter drawRect یا onDraw استعمال نہیں کرتا — تمام ڈرائنگ CustomPainter کے ذریعے ہوتی ہے، جو CustomPaint ویجٹ میں ایمبیڈ ہوتا ہے۔
class CirclePainter extends CustomPainter {
final Color color;
CirclePainter({required this.color});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..style = PaintingStyle.fill
..isAntiAlias = true;
final radius = size.shortestSide / 2 - 4;
canvas.drawCircle(size.center(Offset.zero), radius, paint);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) =>
oldDelegate.color != color;
}
shouldRepaint تعین کرتا ہے کہ آیا CustomPainter کو دوبارہ ڈرا کرنے کی ضرورت ہے۔ صرف اس وقت true لوٹائیں جب رینڈرنگ کو متاثر کرنے والا ڈیٹا تبدیل ہو — رنگ، سائز، چارٹ ڈیٹا۔ RepaintBoundary دوبارہ ڈرائنگ کو ایک علیحدہ پرت میں الگ کرتا ہے — ان ویجٹس کے لیے استعمال کریں جو شاذ و نادر ہی تبدیل ہوتے ہیں۔ Flutter میں setNeedsDisplay یا invalidate نہیں ہے — دوبارہ ڈرائنگ setState یا تبدیلیوں کو سننے والے ValueNotifier کے ذریعے متحرک کی جاتی ہے۔
Flutter LinearGradient، RadialGradient اور SweepGradient کو سپورٹ کرتا ہے — وہی اقسام جو Android میں ہیں۔ Gradient createShader(Rect bounds) کے ذریعے Paint کے لیے Shader بناتا ہے۔ تبدیلیاں canvas.rotate، canvas.scale، canvas.translate اور canvas.skew کے ذریعے انجام دی جاتی ہیں۔ Flutter Transform ویجٹ کے لیے 4x4 تبدیلی میٹرکس (Matrix4) استعمال کرتا ہے۔ Flutter میں ڈرائنگ اینیمیشنز CustomPainter کو دوبارہ ڈرا کرنے کے لیے setState کے ساتھ AnimationController کا استعمال کرتے ہوئے بنائی جاتی ہیں۔
کسٹم ویوز کی درست پیمائش پیش قیاسی انٹرفیس رویے کی بنیاد ہے۔ iOS پر، ویو کا سائز sizeThatFits اور intrinsicContentSize کے ذریعے متعین کیا جاتا ہے۔ sizeThatFits دی گئی رکاوٹوں کے لیے بہترین سائز لوٹاتا ہے۔ intrinsicContentSize — بیرونی رکاوٹوں کے بغیر مواد کا قدرتی سائز۔ Android پر، پیمائش MeasureSpec پیرامیٹرز (UNSPECIFIED، EXACTLY، AT_MOST) کے ساتھ onMeasure میں لاگو کی جاتی ہے۔ Flutter میں، سائز paint(Canvas, Size) کو منتقل کیا جاتا ہے اور computeDryLayout یا LayoutBuilder کے ذریعے حساب کیا جا سکتا ہے۔
intrinsicContentSize CGSize لوٹاتا ہے — اس کے مواد کی بنیاد پر ویو کا قدرتی سائز۔ setContentHuggingPriority اور setContentCompressionResistancePriority کھنچاؤ اور دباؤ کے دوران رویے کو کنٹرول کرتے ہیں۔ sizeThatFits کو Auto Layout میں سائز کا حساب لگانے کے لیے سسٹم کال کرتا ہے۔ کسٹم ویوز کے لیے، intrinsicContentSize کو اوور رائڈ کریں اگر آپ کے جزو کا قدرتی سائز ہو — مثال کے طور پر، ایک دائرہ ہمیشہ 100x100 ہونا چاہیے۔
onMeasure widthMeasureSpec اور heightMeasureSpec قبول کرتا ہے۔ MeasureSpec میں موڈ اور سائز ہوتا ہے: UNSPECIFIED (بغیر رکاوٹوں کے، ویو اپنا سائز خود منتخب کرتا ہے)، EXACTLY (والدین سے عین مطابق سائز)، AT_MOST (زیادہ سے زیادہ سائز)۔ setMeasuredDimension(width, height) پیمائش کا نتیجہ محفوظ کرتا ہے۔ ڈیٹا تبدیل ہونے پر، دوبارہ پیمائش کے لیے requestLayout() کال کریں۔ نیسٹڈ ViewGroup کو بچوں کے عناصر کی ترتیب کے لیے onLayout کو اوور رائڈ کرنے کی ضرورت ہوتی ہے۔
| پلیٹ فارم | پیمائش کا طریقہ | تبدیلی پر کال | واپسی |
|---|---|---|---|
| iOS | sizeThatFits / intrinsicContentSize | setNeedsLayout / invalidateIntrinsicContentSize | CGSize |
| Android | onMeasure / setMeasuredDimension | requestLayout / invalidate | void (سائز محفوظ کرتا ہے) |
| Flutter | computeDryLayout | setState / LayoutBuilder | Size |
computeDryLayout مکمل لے آؤٹ سائیکل کے بغیر سائز کا حساب لگانے کے لیے RenderObject طریقہ ہے۔ LayoutBuilder.getSize — build طریقہ میں دستیاب جگہ حاصل کرنے کا ایک متبادل۔ Flutter میں، کینوس کا سائز paint کو Size کے طور پر منتقل کیا جاتا ہے اور اسے علیحدہ پیمائش کی ضرورت نہیں ہوتی — CustomPainter منتقل کردہ حدود میں ڈرا کرتا ہے۔ تاہم، کسٹم RenderObject کے لیے، performLayout اور computeDryLayout کو اوور رائڈ کرنا ضروری ہے۔
اکثر پوچھے گئے سوالات
drawRect Core Graphics کے ذریعے کسٹم ڈرائنگ کے لیے ایک UIView طریقہ ہے۔ یہ ویو کی پہلی رینڈرنگ پر اور ہر setNeedsDisplay() کال کے بعد کال کیا جاتا ہے۔ لائنوں، اشکال اور متن کے لیے drawRect کے اندر CGContext استعمال کریں۔
View کو بڑھانے والی کلاس بنائیں، onDraw(Canvas canvas) کو اوور رائڈ کریں اور Canvas API استعمال کریں: drawCircle، drawRect، drawPath۔ Paint رنگ، موٹائی اور اسٹائل کنفیگر کرتا ہے۔ اپ ڈیٹ کے لیے invalidate() کال کریں۔
CustomPainter Canvas پر کسٹم ڈرائنگ کے لیے ایک Flutter کلاس ہے۔ paint(Canvas, Size) اور shouldRepaint طریقوں کو لاگو کریں۔ یہ CustomPaint ویجٹ کے ذریعے رکھا جاتا ہے۔ Flutter میں drawRect نہیں ہے — تمام ڈرائنگ CustomPainter کے ذریعے ہوتی ہے۔
iOS پر sizeThatFits اور intrinsicContentSize استعمال کریں۔ Android پر — MeasureSpec کے ساتھ onMeasure۔ Flutter میں، سائز paint(Canvas, Size) کو منتقل کیا جاتا ہے یا computeDryLayout کے ذریعے حساب کیا جاتا ہے۔ ہر پلیٹ فارم اپنا پیمائش کا طریقہ استعمال کرتا ہے۔
کسٹم ویوز منفرد گرافکس، اینیمیشنز، چارٹس اور ایسے عناصر کے لیے ضروری ہیں جنہیں معیاری UIKit یا View سے لاگو نہیں کیا جا سکتا۔ سادہ اسٹائل کے لیے، معیاری اجزاء کو کنفیگر کرنا کافی ہے — بلا ضرورت آرکیٹیکچر کو پیچیدہ نہ بنائیں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔