خبرنامه
 
پست الکترونیکی خود را وارد نمایید
شماره خبر : 1066
تاریخ انتشار :
آشنایی با زبان Visual Format

آشنایی با زبان Visual Format

اگر از برنامه نویسان به نسبت با تجربه سیستم عامل iOS باشید، حتما تا حدی با ابزار Auto Layout آشنایی دارید. همانطور که می دانید این ابزار از چند سال پیش تاکنون مورد استفاده برنامه نویسان زیادی قرار گرفته، و کمک شایانی به آنها در جهت فرامین بصری مختلف در حوضه ظاهر برنامه های کاربردی تحت سیستم عامل iOS کرده است.

 

مقاله دیگر:

 

 آموزش ساخت اپل آیدی رایگان

 

 

اما با مرور زمان شرکت اپل، با پشتیبانی و آپدیت های متعددی که تحت رابط برنامه نویسی Xcode داشته، سبب شده هماهنگی های بیشتری بین این ابزار و محیط برنامه نویسی Xcode به وجود آید و در کل استفاده از آن آسانتر شود.
در ادامه این مقاله آموزشی به شما نشان خواهیم داد تا چگونه از زبان Visual Format تحت رابط برنامه نویسی Swift به منظور ایجاد ضوابط و محدودیت ها(constraintها)ی Auto Layout تحت کد استفاده کنید. با ما همراه باشید.
مقدمه:
در همین ابتدای آموزش لازم است بدانید که فرض ما بر این است که شما پیش از این حداقل آشنایی لازم را با Auto Layout داشته و دارید. در هر صورت اگر پیشتر با این ابزار کار نکرده و تجربه ای ندارید پیشنهاد می کنم به مقالات معتبری که در این زمینه در اینترنت منتشر شده رجوع کرده و سپس با آمادگی لازم ادامه این مقاله را پیگیری کنید.
زبان Visual Format یک زبان اعلانی بوده که به منظور تعریف محدودیت های Auto Layout برای نماها(Viewها) مورد استفاده قرار می گیرید. از همان ابتدا که کار کدنویسی تحت این زبان را آغاز می کنید متوجه نحوه نگارش دستورات یا همان Syntax بسیار گویا و قابل درک آن خواهید شد.
محدودیت های مشخص شده باید به یکباره از خواندن یک دستور Visual Format حذف شده و تا حدی بسیار زیادی نیز باید مانند یک قاعده جاری شوند.
محدودیت های Auto Layout یا همان Auto Layout Constraintها را می توان با اولویت های مختلف، لیوت های عمودی، ایجاد فضا و ابعاد را با استفاده از دستورات زبان Visual Format ایجاد کرد.
این محدودیت ها داخل یک متغیر رشته ای تعریف شده و سپس به متدهای سطح کلاسی همجون constraintsWithVisualFormat:options:metrics:views: و constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: متعلق به کلاس NSLayoutConstraint منتقل داده خواهند شد.
زبان Visual Format مخصوصاً زمانی که نتوان از سازنده رابط یا همان Interface Builder به منظور اضافه کردن محدودیت های Auto Layout استفاده کرد، بسیار مفید خواهد بود. به عنوان مثال در این زمینه می توان به زمانی اشاره کرد که بخشی از رابط کاربری برنامه شما لازم است تا به صورت روالی و سلسله مراتبی ایجاد شود.
ایجاد یک پروژه جدید:
حال اجازه دهید توضیحات را کنار گذاشته و به صورت واقعی یک پروژه ایجاد کرده تا ببینیم چگونه یک زبان Visual Format باید مورد استفاده قرار گرفته و همچنین چطور پروژه های شما می توانند از مزایای این زبان بهره مند شوند. با ما همراه باشید.
مرحله اول:
ابتدا نرم افزار Xcode را باز کرده و سپس از منوی File گزینه New > Project... را طی کنید.حال از رابط کاربری باز شده، و از بخش  iOS Application، گزینه Single View Application  را انتخاب کرده و روی گزینه Next  در پایین این کادر محاوره ای کلیک کنید.

مرحله دوم:
بعد از انجام مرحله گفته شده، حال در رابط نمایان شده مطابق تصویر زیر، نامی برای پروژه خود انتخاب کرده و همچنین مقادیر فیلدهای rganization's name و identifier را نیز به دلخواه پر کنید. سپس مقدار کادر روبروی Devices را تحت Universal تنظیم کرده و بعد روی گزینه  Next در پایین کادر محاوره ای کلیک کنید. حال مکانی را برای ذخیره پروژه برگزیده و در نهایت Swift  را نیز به عنوان زبان برنامه نویسی هدف انتخاب کنید.


ایجاد یک محدودیت برای برنامه Single View:
مرحله اول: تعریف متغیرها
برای شروع کار، ابتدا باید سه متغیر از نوع UIView در رابط کدنویسی برنامه تعریف کنیم.
برای این منظور ابتدا ViewController.swift را باز کرده و سپس سه خط کد زیر را در بخش بالای متد viewDidLoad اضافه کنید. به مانند زیر:

var vwBlue:UIView!
var vwRed:UIView!
var vwGreen:UIView!



مرحله دوم: ارزشدهی اولیه نماها
در این مرحله یک تابع با نام initViews در بخش پایین view controller void به عنوان یک نوع برگشتی از تابع ایجاد کنید.
وظیفه این تابع بدین صورت است که ابتدا نماها را ارزشدهی و مقداردهی اولیه کرده و سپس آنها را به سلسله مراتب نما اضافه خواهد کرد. نکته دیگری که باید مد نظر قرار دهید این است که مطمئن باشید که این تابع را در viewDidLoad بعد از فراخوانی متد viewDidLoad متعلق به superclass مورد فراخوانی قرار می دهید.




func initViews() -> Void
{
    //Initialize
    vwRed = UIView()
    vwBlue = UIView()
    vwGreen = UIView()
    
    //Prep auto layout
    vwRed.setTranslatesAutoresizingMaskIntoConstraints(false)
    vwBlue.setTranslatesAutoresizingMaskIntoConstraints(false)
    vwGreen.setTranslatesAutoresizingMaskIntoConstraints(false)
    
    //Coloring
    vwRed.backgroundColor = UIColor.redColor()
    vwBlue.backgroundColor = UIColor.blueColor()
    vwGreen.backgroundColor = UIColor.greenColor()
    
    //Add them to the view
    self.view.addSubview(vwRed)
    self.view.addSubview(vwBlue)
    self.view.addSubview(vwGreen)
}




زمانی که شما از قابلیت Auto Layout روی نماهای ایجاد شده در کد استفاده می کنید، چند نکته هست که باید با هشیاری تمام مورد توجه قرار دهید.
اولین نکته مربوط به مقدار مشخصه translatesAutoresizingMaskIntoConstraints است. این مشخصه به صورت پیشفرض، تحت مقدار true تنظیم شده است. این حالت بدان معناست که محدودیت های Auto Layout  مبتنی بر مشخصه  autoresizing mask نما، ایجاد خواهد شد.
ما در اینجا می خواهیم این نما وابسته به محدودیت های Auto Layoutای شود که ما اضافه خواهیم کرد. بنابراین برای نیل به این هدف باید این مشخصه تحت مقدار false تنظیم شود.
دومین نکته ای که باید مورد توجه قرار دهید در واقع چرخه حیات نما یا همان view life cycle است. دقت داشته باشید که پیش از اینکه محدودیت های Auto Layout بتوانند به نما اضافه شوند، ابتدا باید صددرصد به superview اضافه شوند.
حال در صورتی که این اتفاق رخ ندهد، با یک خطای زمان اجرا مواجه خواهید شد.
بازفراخوانی Auto Layout مورد بحث سبب می شود مکان و موقعیت نماها مبتنی بر روابطشان تعریف شود.
حال اگر یک نما هیچ superviewای نداشته باشید، سیستم عامل هیچ اتصال مرجعی برای مرتبط کردن محدودیت های superview به آن نخواهد داشت.

مرحله سوم: ایجاد محدودیت هایی برای یک Single View:
حال در این مرحله اجازه دهید کار خود را با یک مثال ساده از زبان Visual Format آغاز کنیم.
برای نمای red یا همان vwRed، ما محدودیت های Auto Layout را اضافه کرده تا اندازه آنرا با superviewی آن یکسان کرده و مطابق کنیم. این فرایند در جایی مناسب و مفید خواهد بود که شما بخواهید یک تصویر پس زمینه به آن اضافه کنید.
نکته ای که باید دقت داشته باشید این است که پیش از اینکه بتوانید زبان Visual Format را مورد استفاده قرار دهید، تمامی نماهایی که ما لازم داریم باید در داخل یک dictionary تحت حالت رفرنس درآیند. تنها در این حالت است که نماهای موجود به واسطه زبان Visual Format شناسه گذاری خواهند شد.
حال در ادامه کار، یک تابع با نام createConstraints و با نوع برگشتی void در بخش انتهایی کلاس view controller ایجاد کنید. به هیچ وجه در اینجا نگران نحو و املای دستورات نباشید.
در ادامه نگاهی به نحوه پیاده سازی تابع createConstraints خواهیم داشت.


func createConstraints() -> Void
{
    //Views to add constraints to
    let views = Dictionary(dictionaryLiteral: ("red",vwRed),("blue",vwBlue),("green",vwGreen))
    
    //Horizontal constraints
    let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[red]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(horizontalConstraints)
    
    //Vertical constraints
    let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|[red]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(verticalConstraints)
}



مرحله چهارم: کامپایل و اجرا

در این مرحله، تابع مذکور را در انتهای تابع initViewsا که پیش از این نسبت به ایجاد آن اقدام کردیم، فراخوانی کنید. حال برای کامپایل و اجرای پروژه، کلید میانبر Command + R را زده و یا به سادگی می توانید روی دکمه Play که در سمت چپ و بالای صفحه قرار گرفته، کلیک کنید تا برنامه کامپایل شده و اجرا گردد. با انجام هر یک از دو روش گفته شده، صفحه ای قرمز رنگ به مانند زیر را خواهید دید که همانطور که برنامه ریزی شده، کل صفحه را اشغال می کند:


مرحله ۴:بررسی نحو و املای زبان Visual Format:
به طور کلی زمانی که شما از زبان Visual Format استفاده می کنید، محدودیت های Auto Layout در دو حالت افقی یا عمودی تعریف می شوند. شما همچنین می توانید نسبت به تنظیم ارتفاع یا عرض یک نما زمانی که در حال اعلان محدودیت های عمومی و افقی هستید، اقدام کنید. حال اجازه دهید تا نگاه دقیقتری به اولین رشته ای که برای ایجاد محدودیت افقی ایجاد کردیم، داشته باشیم. با ما همراه باشید.


"H:|[red]|"


اول از همه ما متوجه هستیم که این رشته در واقع یک محدودیت افقی ای بوده که در ابتدای رشته با حرف H شروع شده است. محدودیت افقی، مقدار پیشفرض است یعنی اگر مقدار آنرا هم تعیین نکنید، محدودیت افقی خواهد بود مگر اینکه صریحاً مشخص کنید. اما به هر حال  خوبه که برای خوانا بودن روند کار، حرف H را لحاظ کنیم.
بعد از حرف H همانطور که از رشته بالا مشخص است، یک علامت دونقطه(کلن،colon) قرار گرفته است. بعد از علامت دو نقطه نیز یک نماد پایپ قرار گرفته که به منظور نمادین کردن superviewی نما، مورد استفاده قرار گرفته است. همچنین شما می توانید برای اضافه کردن فضا بین دو جزء، از نماد - (خط تیره-دش) استفاده کرده، و مقادیر عددی را نیز می توانید بین آنها قرار داده تا یک فضای متغیر یا ثابت ایجاد کنید. نماها، به واسطه کلیدهای ارائه شده در dictionaryای که به constraintsWithVisualFormat منتقل شده، در حال رفرنس یا همان مرجع قرار گرفته اند. همچنین هر نما توسط براکت های مجعر، پوشانده شده اند.
دقت داشته باشید که چطور کل رشته‌ی موجود به صورت ظاهری تصویر موجود از شبیه ساز را هماهنگ کرده است.
در واقع الگوی آن به گونه ای تنظیم شده که درست به مانند یک قاعده عمل می کند.
5-ایجاد محدودیت هایی برای چندین نما:
حال که با توجه به توضیحات گفته شده، حداقل درک و آگاهی از نحوه نوشتار یا همان سینتکس این زبان به دست آورده اید،  وقت آن رسیده تا دست به کار شده و تابع createConstraints را به منظور اضافه کردن محدودیت های Auto Layout به دو نما، دست خوش تغییراتی قرار دهیم. با ما همراه باشید.
مرحله اول: ویرایش محدودیت افقی
در همین ابتدای کار، تغییرات زیر را در تابع createConstraints و تحت متغیر horizontalConstraints اعمال کنید:


//Horizontal constraints
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[red(>=100,<=200)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views)
self.view.addConstraints(horizontalConstraints)


اگر کمی دقت کنید، می بینید که همین تکه کد انعطاف واقعی زبان Visual Format را به ما نشان داده و گواه بر این است که می توان قابلیت ها و تغییرات گسترده ای را با این ابزار در برنامه های خودمان اعمال کنیم.
همانطور که ملاحظه می کنید دستورات بالا وظیفه ایجاد یک سری از محدودیت های Visual Format  را بر عهده دارند. بعد از نام نمای مشخص شده، اندازه های افقی در داخل پرانتزها تعریف شده اند. حال برای نمای قرمز، اندازه را باید بزرگتر یا مساوی 100 تنظیم کرده، اما از آن طرف هم نباید از 200 واحد بیشتر تجاوز کند.
نمای آبی رنگ هم مشخص می کند که اندازه افقی آن باید با نمای قرمز و به واسطه دستور ==red در داخل پرانتز یکسان و یکی باشد.
در واقع این یک روش مناسب است که به واسطه آن ما می توانیم مشخص کنیم چندین نما باید از اندازه یکسانی برخوردار باشند.
حال در اینجای کار، پروژه را در شبیه ساز iOS کامپایل و اجرا نمایید. نتیجه حاصله باید به مانند تصویر زیر به نظر برسد:

مرحله دوم: اضافه کردن اولویت ها
در این مرحله در حالی که برنامه ما در شبیه ساز iOS در حالت اجرا قرار دارد، کلید میانبر Command + Left Arrow  را به منظور تغییر جهت نمایش شبیه ساز iOS به حالت landscape فشار دهید. همینطور که برنامه به روال طبیعی و بدون مشکل خود در حالت اجرا قرار دارد، با انجام فرایند گفته شده، یک پیغام خطا در رابط کنسول نرم افزار Xcode نمایش داده خواهد شد. در واقع منظور اخطار نمایش داده شده این است که به ما اعلام کند که ایجاد برخی از محدودیت های Auto Layout مورد رضایت و منطق برنامه واقع نشده است. البته دقت داشته باشید که این اخطار موجب توقف یا همان کرش شدن برنامه شما نخواهد شد، لیکن ممکن است منجر به ظهور نتایج غیرقابل انتظاری در داخل رابط کاربری برنامه شما شود.


علت این اخطار از آن جهت است که دو نمایی که ما ایجاد کردیم نمی توانند 200 واحد پهنا یا همان عرض داشته و همچنین زمانی که دستگاه یا شبیه ساز iOS در حال نمایش landscape قرار گرفته، نمی توان فضایی بین آنها اعمال نکرد.
نکته جالبی که خوب است بدانید این است که Auto Layout این نوع مسائل و پیشامدها را با استفاده از اولویتها به خوبی حل و فصل می کند. زبان Visual Format این امکان را در اختیار شما قرار داده تا بتوانید اولویت ها را با استفاده از نماد @ تعریف کنید. حال در ادامه کار متغیر horizontalConstraints را مطابق الگوی زیر، ویرایش کنید:


//Horizontal constraints
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[red(>=100,<=200@20)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views)


از آن جهت که در حال حاظر نماهای آبی و قرمز دارای یک اولویت پایین در محدودیت مختصات عرضشان( @20) هستند، سیستم Auto Layout، این محدودیت ها را خواهد شکست و آنهارا با مقدار درست و مناسب در زمان اجرا تامین و تغذیه خواهد کرد.
حال در اینجای کار، یک بار دیگر برنامه را اجرا کرده و جهت نمایش برنامه را تحت landscape تنظیم کنید. حال مشاهده خواهید کرد که در این مرحله، نماها فضای اضافه را پر کرده و نرم افزار Xcode نیز هیچ هشدار یا پیغام خطایی به شما نشان نخواهد داد.

مرحله سوم: اضافه کردن محدودیت ها به نمای Bottom
در این مرحله ما می خواهیم محدودیت هایی را برای نمای سبز ایجاد کنیم. برای این منظور ساختار پیاده سازی تابع createConstraints را مطابق به دستورات زیر، تحت ویرایش قرار دهید:


func createConstraints() -> Void
{
    //Views to add constraints to
    let views = Dictionary(dictionaryLiteral: ("red",vwRed),("blue",vwBlue),("green",vwGreen))
    
    //Horizontal constraints
    let horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[red(>=100,<=200@20)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(horizontalConstraintsRedBlue)
    let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat("H:|[green]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(horizontalConstraintsGreen)
    
    //Vertical constraints
    let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat("V:|[red]-10-[green(40)]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(verticalConstraintsRed)
    let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat("V:|[blue]-10-[green(40)]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(verticalConstraintsBlue)
}


از آن جهت که محدودیت horizontalConstraintsGreen، یک عرض    یا فضای مشخص را برای superviewی خود تعریف نمی کند، وظیفه اندازه گیری طول کامل را بر عهده می گیرد. از آن طرف محدودیت عمودی نیز این اطمینان را ایجاد می کند که ارتقاع آن 40 واحد بوده و همچنین 10 واحد فضا نیز بین نماهای آبی و قرمز ایجاد خواهد شد.

مرحله چهارم: اضافه کردن واحدهای اندازه گیری
برای اینکه مطمئن شویم همه چیز درست و به جا به وظیفه خود عمل می کند، ما می خواهیم از یک دیکشنری که در برگیرنده واحد های سنجش باشد در بخش اعلانات محدودیت ها استفاده کنیم. حال برای این منظور یک دیکشنری، بلافاصله بعد از از اعلان دیکشنری views مطابق دستورات زیر ایجاد کنید:


let metrics = Dictionary(dictionaryLiteral: ("spacing", 10),("lowWidth",100),("highWidth",200),("priority",20),("redBlueSpacing",0),("greenHeight",40))



حال به جای استفاده از مقادیر hard-coded، ما می توانیم از مقادیر دیکشنری metrics استفاده کرده که سبب می شود اعلانات محدودیتها بسیار بیشتر قابل درک و فهم شوند.   
در ادامه کار، و برای آخرین بار تابع createConstraints را با استفاده از دیکشنری جدید metrics و مطابق زیر تحت ویرایش قرار دهید:


func createConstraints() -> Void
{
    //Views to add constraints to
    let views = Dictionary(dictionaryLiteral: ("red",vwRed),("blue",vwBlue),("green",vwGreen))
    //Metrics for Visual Format string
    let metrics = Dictionary(dictionaryLiteral: ("spacing", 10),("lowWidth",100),("highWidth",200),("priority",20),("redBlueSpacing",0),("greenHeight",40))
    
    //Horizontal constraints
    let horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat("H:|-spacing-[red(>=lowWidth,<=highWidth@priority)]-redBlueSpacing-[blue(==red)]-spacing-|", options: nil, metrics: metrics, views: views)
    self.view.addConstraints(horizontalConstraintsRedBlue)
    let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat("H:|[green]|", options: nil, metrics: nil, views: views)
    self.view.addConstraints(horizontalConstraintsGreen)
    
    //Vertical constraints
    let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat("V:|[red]-spacing-[green(greenHeight)]|", options: nil, metrics: metrics, views: views)
    self.view.addConstraints(verticalConstraintsRed)
    let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat("V:|[blue]-spacing-[green(greenHeight)]|", options: nil, metrics: metrics, views: views)
    self.view.addConstraints(verticalConstraintsBlue)
}


6-محدودیت های زبان Visual Format:
شاید تا العان تعجب کرده باشید که چرا ارتفاع نمای سبز، دوبار تعریف شد. در واقع علت این امر از آن جهت است که زبان Visual Format به صورت سطر و ستون کار می کند. در حقیقت زمانی که از زبان Visual Format استفاده می کنیم باید به فکر اضافه کردن محدودیت های سمت چپ به راست تحت یک سطر از نما برای محدودیت های افقی باشید.
از آن طرف برای محدودیت های عمودی، لازم است تا تفکر خود را روی ضوابط و شرایط ستونها قرار دهید.
اغلب محدودیت های Auto Layout@ که شما استفاده خواهید کرد را می توان با کمک زبان Visual Format مشخص کرد. اما در هر صورت استثناعاتی نیز در برخی موارد وجود دارد. به عنوان مثال یک محدودیت با نرخ نسبت ثابت را نمی توان با استفاده از این زبان ایجاد کرد. به طور کلی این حالت را نمی توان با ساختار دستوری این زبان ایجاد کرد چرا که رشته زیر قابلیت تبدیل ندارد:
H:|imageView.width = 2 * imageView.height|
در هر صورت شما هنوز هم می توانید برای به دست آوردن این نوع از محدودیت ها از متد قدیمی constraintWithItem در لابه لای کدهای Auto Layout بهره ببرید.
نتیجه گیری:
زمانی که شما نیاز دارید محدودیت های Auto Layout را از طریق کد ایجاد کنید، زبان Visual Format در این زمینه کمک شایانی به شما خواهد کرد. در واقع شما به جای اینکه مجبور باشید محدودیت ها را به صورت تک تک ایجاد کنید، زبان Visual Format این امکان را در اختیار شما خواهد داد تا نسبت به ایجاد چندین محدودیت تنها با یک خط کد اقدام کنید.
پیش از آنکه قابلیت Auto Layout در دسترس توسعه دهندگان و برنامه نویسان قرار بگیرد، بررسی نحوه تغییر اندازه نماها برای دستگاه های مختلف کاری بس دشوار و طاقت فرسا بود. حال دیگر با کمک Auto Layout و زبان Visual Format، این فرایند بسیار قابل فهم تر شده و ایجاد رابطهای کاربری مناسب و کاربرپسند در بین انبوه دستگاه ها،  راحتتر و سهلتر شده است.
مقاله امروز هم به پایان رسید امیدوارم استفاده لازم را برده باشید.

مترجم: هادی نجار

 

تعداد بازدید : 457

ارسال نظر

سوال امنیتی : مجموع دو عدد 5 و 2 =