Auto Layout হল Apple-এর অ্যাডাপ্টিভ ইন্টারফেস এলিমেন্ট পজিশনিং সিস্টেম, যা গাণিতিক সীমাবদ্ধতার (constraints) উপর ভিত্তি করে। iOS 6 (2012)-এর জন্য তৈরি, Auto Layout আপনাকে এমন ইন্টারফেস তৈরি করতে দেয় যা সব ডিভাইসে সঠিকভাবে প্রদর্শিত হয় — iPhone SE (4.7″) থেকে iPad Pro (12.9″) এবং Dynamic Island পর্যন্ত। Apple WWDC Session 202 (2024) অনুযায়ী, App Store-এর 90% এর বেশি অ্যাপ Auto Layout বা এর ডিক্লারেটিভ অল্টারনেটিভ — SwiftUI layout system ব্যবহার করে। Constraints UI এলিমেন্টের মধ্যে নির্ভরশীলতা রৈখিক সমীকরণের মাধ্যমে বর্ণনা করে: view1.leading = view2.trailing + 8.
মূল পয়েন্ট
Auto Layout হল Apple-এর অ্যাডাপ্টিভ লেআউট সিস্টেম যা UI এলিমেন্ট পজিশন করার জন্য গাণিতিক সীমাবদ্ধতা (constraints) ব্যবহার করে। ফ্রেম-ভিত্তিক লেআউটের (frame-based layout) বিপরীতে, যেখানে প্রতিটি এলিমেন্টের নির্দিষ্ট কোঅর্ডিনেট x, y, width, height থাকে, Auto Layout এলিমেন্টের মধ্যে সম্পর্ক বর্ণনা করে: «বাটনটি প্যারেন্টের ডান প্রান্ত থেকে 8pt দূরে» অথবা «টেক্সট ফিল্ডের প্রস্থ স্ক্রিনের অর্ধেক প্রস্থের সমান»। মেকানিজমটি Cassowary অ্যালগরিদমের উপর ভিত্তি করে, যা University of Washington (Greg J. Badros, 1999)-এ তৈরি এবং Apple iOS 6-তে বাস্তবায়ন করেছে। Cassowary প্রায়োরিটি সহ রৈখিক অসমতার একটি সিস্টেম সমাধান করে — Required (1000), Default High (750), Default Low (250) — যা সীমাবদ্ধতা সংঘাত পরিচালনার অনুমতি দেয়। Auto Layout তিনটি সাইজ টাইপ সমর্থন করে: intrinsic (কন্টেন্ট দ্বারা নির্ধারিত এলিমেন্টের প্রাকৃতিক আকার), explicit (স্পষ্টভাবে নির্ধারিত সীমাবদ্ধতা) এবং compressible/stretchable (Content Hugging Priority এবং Compression Resistance Priority-এর মাধ্যমে রাবার মোড)।
Auto Layout-এর প্রতিটি UI এলিমেন্টের একটি Intrinsic Content Size থাকে — এর কন্টেন্ট দ্বারা নির্ধারিত একটি প্রাকৃতিক আকার। UILabel-এর জন্য এটি টেক্সট এবং ফন্টের উপর নির্ভর করে, UIImageView-এর জন্য — ছবির মাত্রার উপর। Content Hugging Priority (প্রসারিত হওয়ার প্রতিরোধ) এবং Compression Resistance Priority (সংকুচিত হওয়ার প্রতিরোধ) উপলব্ধ স্থান পরিবর্তন হলে এলিমেন্টের আচরণ নিয়ন্ত্রণ করে। স্ট্যান্ডার্ড মান: hugging-এর জন্য 251 এবং compression resistance-এর জন্য 749। যদি দুটি এলিমেন্ট স্থানের জন্য প্রতিযোগিতা করে, প্রায়োরিটি নির্ধারণ করে কোনটি প্রথমে প্রসারিত হবে। এই প্রায়োরিটি বোঝা Ambiguous Layout (অস্পষ্ট লেআউট) সমাধানের চাবিকাঠি, যা Xcode ডিবাগারে হাইলাইট করে।
একটি constraint সমীকরণ দ্বারা বর্ণিত হয়: view1.attribute = multiplier × view2.attribute + constant। অ্যাট্রিবিউটগুলির মধ্যে রয়েছে leading, trailing, top, bottom, centerX, centerY, width, height, firstBaseline, lastBaseline। Multiplier আনুপাতিক সম্পর্কের জন্য ব্যবহৃত হয় (view1-এর প্রস্থ = 0.5 × superview-এর প্রস্থ)। Constant একটি নির্দিষ্ট অফসেট নির্ধারণ করে (leading = superview.leading + 16)। Interface Builder টুলস Ctrl-ড্রাগের মাধ্যমে দৃশ্যমানভাবে constraints তৈরি করতে দেয়, কিন্তু জটিল লেআউটের জন্য NSLayoutConstraint বা VFL (Visual Format Language)-এর মাধ্যমে প্রোগ্রামেটিক তৈরি প্রয়োজন, যা Apple iOS 9 থেকে NSLayoutConstraint-এ প্রতিস্থাপনের সুপারিশ করে।
Constraints সিস্টেমটি একটি রৈখিক প্রোগ্রামিং সমস্যা হিসেবে সমাধান করা হয়: Cassowary অ্যালগরিদম তাদের প্রায়োরিটি বিবেচনা করে সমস্ত সীমাবদ্ধতা পূরণ করে এমন সব এলিমেন্টের সর্বোত্তম বিন্যাস খুঁজে পায়। যদি constraints পরস্পরবিরোধী হয়, তাহলে Unsatisfiable Layout ঘটে — একটি ব্যতিক্রম যা Xcode বিস্তারিত সংঘাত বিবরণ সহ লগ করে। যদি কমপক্ষে একটি এলিমেন্টের অবস্থান নির্ধারণের জন্য পর্যাপ্ত constraints না থাকে, তাহলে Ambiguous Layout ঘটে — এলিমেন্টগুলি ইচ্ছামত অবস্থানে প্রদর্শিত হয়। Apple একটি ন্যূনতম সেট সুপারিশ করে: প্রতিটি এলিমেন্টের জন্য position (x, y) এবং size (width, height) স্পষ্টভাবে বা intrinsic content size-এর মাধ্যমে সেট করতে হবে। Constraints প্রথম-শ্রেণীর হতে পারে: লিডিং এলিমেন্ট (যেমন superview) এবং ট্রেইলিং (চাইল্ড ভিউ) একটি শ্রেণিবিন্যাস তৈরি করে।
Cassowary রৈখিক অসমতার সিস্টেম সমাধানের জন্য Sequential Quadratic Programming পদ্ধতি ব্যবহার করে। প্রতিটি constraint-এর 1 থেকে 1000 পর্যন্ত প্রায়োরিটি থাকে। Required (1000) একটি বাধ্যতামূলক সীমাবদ্ধতা; যদি এটি পূরণ করা না যায়, অ্যাপ NSConstraintException-এর সাথে ক্র্যাশ করে। Default High (750) সুপারিশকৃত; Default Low (250) সবচেয়ে কম গুরুত্বপূর্ণ। সংঘাতের সময়, Cassowary কম প্রায়োরিটির সীমাবদ্ধতা শিথিল করে। উদাহরণস্বরূপ, যদি দুটি এলিমেন্টের নির্দিষ্ট প্রস্থ প্রয়োজন কিন্তু স্ক্রিন খুব সংকীর্ণ হয়, কম প্রায়োরিটির constraint শিথিল করা হয়। Xcode Debug View Hierarchy (Xcode 6 থেকে উপলব্ধ ডিবাগিং টুল) শুধুমাত্র Required constraints-এর সমস্যা হাইলাইট করে — বাকিগুলি ত্রুটি ছাড়াই পরিচালিত হয়।
UIStackView হল একটি কন্টেইনার যা iOS 9 (2015)-এ প্রবর্তিত হয়েছে এবং নেস্টেড arrangedSubviews-এর জন্য স্বয়ংক্রিয়ভাবে constraints তৈরি এবং পরিচালনা করে। UIStackView দুটি অক্ষ সমর্থন করে: horizontal (অনুভূমিক) এবং vertical (উল্লম্ব)। Distribution সেটিংস স্থান বিতরণ নির্ধারণ করে: fill (hugging priority অনুযায়ী আনুপাতিক ভরাট), fillEqually (সমান আকার), fillProportionally (intrinsic content size-এর অনুপাতে), equalSpacing (সমান ব্যবধান), equalCentering (কেন্দ্রের মধ্যে সমান দূরত্ব)। Alignment ক্রস-অক্ষ সারিবদ্ধকরণ নির্ধারণ করে: fill, leading, center, trailing (অনুভূমিকের জন্য) বা fill, top, center, bottom (উল্লম্বের জন্য)। UIStackView স্বয়ংক্রিয়ভাবে spacing, baseline alignment এবং Dynamic Type অভিযোজন পরিচালনা করে।
import UIKit
class StackViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let stack = UIStackView()
stack.axis = NSLayoutConstraint.Axis.vertical
stack.distribution = .fillEqually
stack.spacing = 8
stack.translatesAutoresizingMaskIntoConstraints = false
let label = UILabel()
label.text = "Auto Layout Guide"
label.font = UIFont.preferredFont(forTextStyle: .headline)
let button = UIButton(type: .system)
button.setTitle("Apply", for: .normal)
stack.addArrangedSubview(label)
stack.addArrangedSubview(button)
view.addSubview(stack)
NSLayoutConstraint.activate([
stack.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stack.centerYAnchor.constraint(equalTo: view.centerYAnchor),
stack.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 16),
stack.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -16)
])
}
}কোডটি দুটি এলিমেন্ট (UILabel এবং UIButton) সহ একটি উল্লম্ব UIStackView তৈরি করে, 8pt ব্যবধানে সমানভাবে বিতরণ করা (fillEqually)। স্ট্যাকটি স্ক্রিনে কেন্দ্রীভূত এবং প্রান্ত থেকে কমপক্ষে 16pt মার্জিন রয়েছে। প্রোগ্রামেটিকভাবে constraints তৈরি করার সময় translatesAutoresizingMaskIntoConstraints = false প্রয়োজন — এটি ছাড়া Auto Layout কাজ করে না। IT Sectr-এ, UIStackView iOS প্রকল্পের 80% স্ক্রিনে অ্যাডাপ্টিভ ফর্ম, সেটিংস তালিকা এবং কার্ড তৈরি করতে ব্যবহৃত হয়।
UIStackView নেস্টেড করা যেতে পারে: একটি উল্লম্ব স্ট্যাকের ভিতরে একটি অনুভূমিক স্ট্যাক জটিল লেআউটের জন্য একটি স্ট্যান্ডার্ড প্যাটার্ন। বাইরের স্ট্যাক সারি পরিচালনা করে, ভিতরের স্ট্যাক প্রতিটি সারির ভিতরে কলাম পরিচালনা করে। প্রতিটি স্তরে axis, alignment এবং distribution-এর সংমিশ্রণ একটি একক ম্যানুয়াল constraint ছাড়াই কার্যত সীমাহীন নমনীয়তা প্রদান করে। Apple UIKit-এ UIStackView-কে প্রাথমিক লেআউট টুল হিসেবে সুপারিশ করে, শুধুমাত্র স্ট্যাক দ্বারা কভার না হওয়া ক্ষেত্রে ম্যানুয়াল NSLayoutConstraint-এ আশ্রয় নেয়: ওভারল্যাপিং ভিউ, সঠিক পিক্সেল পজিশনিং, কাস্টম bounds অ্যানিমেশন।
NSLayoutConstraint কোডে পৃথক সীমাবদ্ধতা তৈরির জন্য একটি প্রোগ্রামেটিক API। প্রতিটি constraint প্যারামিটার সহ একটি ইনিশিয়ালাইজারের মাধ্যমে তৈরি করা হয়: item, attribute, relatedBy, toItem, attribute, multiplier, constant। iOS 9 থেকে, Apple Anchor API চালু করেছে — view.leadingAnchor, view.trailingAnchor, view.topAnchor, view.bottomAnchor, view.centerXAnchor, view.centerYAnchor, view.widthAnchor, view.heightAnchor বৈশিষ্ট্যের মাধ্যমে আরও পড়া যায় এমন সিনট্যাক্স। Anchor API স্বয়ংক্রিয়ভাবে relatedBy = .equal সেট করে এবং Anchors থেকে First Item/Second Item ব্যবহার করে, যা ক্লাসিক NSLayoutConstraint-এর তুলনায় কোড 40% কমায়।
import UIKit
class ConstraintViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let childView = UIView()
childView.backgroundColor = .systemBlue
childView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(childView)
NSLayoutConstraint.activate([
childView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 24),
childView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
childView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
childView.heightAnchor.constraint(equalToConstant: 120),
childView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -24)
])
}
}কোডটি childView-কে safeAreaLayoutGuide (top) এবং স্ক্রিন প্রান্ত (leading/trailing) থেকে মার্জিন সহ অবস্থান করে। bottom-এর জন্য lessThanOrEqualTo নিশ্চিত করে যে ভিউ নিচের সীমানা অতিক্রম না করে। Anchor API একটি কম্পাইল-টাইম ব্যতিক্রম ছুঁড়ে দেয় যদি anchors বেমানান হয় (উদাহরণস্বরূপ, leadingAnchor-কে rightAnchor-এর সাথে মেশানো), রানটাইম ত্রুটি প্রতিরোধ করে। Apple iOS 9 থেকে প্রোগ্রামেটিক Auto Layout-এর জন্য Anchor API-কে মানদণ্ড হিসেবে সুপারিশ করে।
Safe Area হল স্ক্রিনের সেই এলাকা যা সিস্টেম এলিমেন্ট — Dynamic Island, Notch, Status Bar, Home Indicator, গোলাকার কোণ দ্বারা আবৃত নয়। iOS 11-এ, Apple topLayoutGuide/bottomLayoutGuide-কে safeAreaLayoutGuide-এ প্রতিস্থাপন করেছে, যা স্বয়ংক্রিয়ভাবে ডিভাইস ওরিয়েন্টেশন এবং স্ক্রিন কাটআউটের উপস্থিতির সাথে খাপ খায়। Layout Margins হল ডিফল্ট অভ্যন্তরীণ ভিউ মার্জিন (iOS-এ 16pt, iPadOS-এ 20pt)। UILayoutGuide-এর জন্য আপনি RIGHT-TO-LEFT লোকালাইজেশন বিবেচনা করে কাস্টম directionalLayoutMargins সেট করতে পারেন। Auto Layout anchors-এ safeAreaLayoutGuide ব্যবহার করার সময় স্বয়ংক্রিয়ভাবে safe area সম্মান করে।
Dynamic Island (iPhone 14 Pro এবং নতুন) এবং Notch (iPhone X–13) সহ ডিভাইসগুলিতে, Safe Area পোর্ট্রেটে উপরের দিকে 44pt (সক্রিয় অবস্থায় Dynamic Island-এর সাথে 59pt) বাদ দেয়। Home Indicator নীচে 34pt যোগ করে। সঠিক অভিযোজনের জন্য, সমস্ত উপরের constraints safeAreaLayoutGuide.topAnchor-এর সাথে সংযুক্ত করা উচিত, view.topAnchor-এর সাথে নয়। নিচের constraints safeAreaLayoutGuide.bottomAnchor বা Home Indicator-এর জন্য মার্জিন সহ view.bottomAnchor-এর সাথে সংযুক্ত করা উচিত। IT Sectr-এ, আমরা iPhone SE (2022), iPhone 14 Pro Max এবং iPad Pro 12.9″ সিমুলেটরে সব স্ক্রিন পরীক্ষা করি — তিনটি ডিভাইস যা সব safe area ভ্যারিয়েশন কভার করে।
Auto Layout-এর সাথে কাজ করার সময় সবচেয়ে সাধারণ ভুল: ভুলে যাওয়া translatesAutoresizingMaskIntoConstraints = false, বিরোধপূর্ণ Required constraints (প্রায়োরিটি 1000), Ambiguous Layout (অবস্থান নির্ধারণের জন্য অপর্যাপ্ত constraints), মাল্টি-লাইন UILabel-এর জন্য ভুল Content Hugging Priority, এবং leading/trailing-কে left/right anchors-এর সাথে মেশানো। Xcode 15+ Runtime Issue Navigator-এ লেআউট সমস্যা প্রদর্শন করে এবং স্বয়ংক্রিয় সংশোধন অফার করে। জটিল লেআউটের জন্য, Debug View Hierarchy ব্যবহার করুন: হলুদ মার্কার ambiguous layout নির্দেশ করে, লাল unsatisfiable নির্দেশ করে।
| ভুল | কারণ | সমাধান |
|---|---|---|
| translatesAutoresizingMaskIntoConstraints = true | Auto Layout ভিউয়ের জন্য সক্রিয় নয় | সব প্রোগ্রামেটিক ভিউয়ের জন্য false সেট করুন |
| Unsatisfiable Layout | Required (1000) constraints-এর দ্বন্দ্ব | একটি প্রায়োরিটি Default High (750)-এ কমিয়ে দিন |
| Ambiguous Layout | x/y/w/h-এর জন্য অপর্যাপ্ত constraints | অনুপস্থিত constraint যোগ করুন বা intrinsic size পরীক্ষা করুন |
| UILabel-এ টেক্সট কাটছাঁট | Content Hugging Priority প্রতিযোগীর চেয়ে কম | hugging priority 252+ বাড়ান |
| LTR/RTL anchors মেশানো | leadingAnchor-এর সাথে rightAnchor | RTL সমর্থনের জন্য শুধুমাত্র leading/trailing ব্যবহার করুন |
সচরাচর জিজ্ঞাসা
ফ্রেম-ভিত্তিক লেআউট প্রতিটি এলিমেন্টের জন্য নির্দিষ্ট কোঅর্ডিনেট x, y, width, height নির্ধারণ করে। Auto Layout গাণিতিক সীমাবদ্ধতা (constraints) ব্যবহার করে — এলিমেন্টের মধ্যে সম্পর্ক: «label.leading = button.trailing + 8»। ফ্রেম-ভিত্তিক লেআউট স্ক্রিন সাইজের সাথে খাপ খায় না; Auto Layout ঘূর্ণন, Split View বা Dynamic Type পরিবর্তনে স্বয়ংক্রিয়ভাবে অবস্থান পুনঃগণনা করে।
UIStackView রৈখিক লেআউটের জন্য সর্বোত্তম: সারি, কলাম, ফর্ম, প্যারামিটার তালিকা। NSLayoutConstraint ওভারল্যাপিং ভিউ, সঠিক পিক্সেল পজিশনিং, কাস্টম bounds অ্যানিমেশন এবং যেসব ক্ষেত্রে স্থান বিতরণ অসম এবং UIStackView distribution-এর দ্বারা আচ্ছাদিত নয় সেগুলির জন্য প্রয়োজন। বাস্তবে, 80% লেআউট UIStackView দিয়ে সমাধান করা হয়, 20% ম্যানুয়াল constraints দিয়ে।
Content Hugging Priority (প্রসারিত হওয়ার প্রতিরোধ) একটি প্রায়োরিটি যা নির্ধারণ করে যে একটি এলিমেন্ট Intrinsic Content Size-এর বাইরে তার আকার বৃদ্ধির কতটা প্রতিরোধ করে। ডিফল্ট মান 251। যদি দুটি এলিমেন্ট খালি স্থানের জন্য প্রতিযোগিতা করে, বেশি hugging priority-র এলিমেন্টটি তার আকারে থাকে যখন দ্বিতীয়টি প্রসারিত হয়। Compression Resistance Priority (ডিফল্ট 749) সংকোচনের জন্য একইভাবে কাজ করে।
Auto Layout স্বয়ংক্রিয়ভাবে Dynamic Type-এর সাথে খাপ খায় যদি constraints লেবেলের intrinsic content size ব্যবহার করে। ফন্ট সাইজ বাড়লে, UILabel প্রসারিত হয়, constraints-এর মাধ্যমে প্রতিবেশী এলিমেন্ট স্থানচ্যুত করে। distribution = fillProportionally সহ UIStackView নতুন intrinsic size-এর অনুপাতে স্থান পুনঃবিতরণ করে। Safe Area এবং Layout Marginsও অ্যাক্সেসিবিলিটি সেটিংস সম্মান করে।
Unsatisfiable Layout ঘটে যখন দুটি Required (priority = 1000) constraints পরস্পরবিরোধী হয়: উদাহরণস্বরূপ, view.leading = superview.leading + 16 এবং view.trailing = superview.leading + 200 যখন superview-এর প্রস্থ 100pt। Cassowary অ্যালগরিদম কোনও সমাধান খুঁজে পায় না এবং অ্যাপ NSConstraintException-এর সাথে ক্র্যাশ করে। সমাধান হল বিরোধপূর্ণ constraints-এর একটির প্রায়োরিটি Default High (750)-এ কমানো।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন