آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

آموزش پیاده سازی قابلیت پیمایش (navigation)درSwift

پیاده سازی قابلیت پیمایش (navigation)

در این مبحث، با بهره گیری از ابزاری نظیر navigation controller و segue ها قابلیت پیمایش را در اپلیکیشن FoodTracker پیاده سازی خواهید نمود. در پایان مبحث، قادر خواهید به راحتی بین صفحات مختلف برنامه راهبری نموده و با آن ها تعامل داشته باشید.
ظاهر برنامه در پایان به صورت زیر خواهد بود:
پیاده سازی قابلیت پیمایش (navigation)

آنچه خواهید آموخت
  • یک view controller از قبل موجود را داخل یک navigation controller در storyboard جاسازی نمایید/بگنجانید.
  • جهت انتقال یا پیمایش بین دو view controller از segue ها بهره بگیرید
  • از طریق کادر attribute inspector، خصیصه ها (attribute های) یک segue را در storyboard ویرایش نمایید.
  • با بهره گیری از متد prepareForSegue(_:sender:) داده ها را بین view controller ها رد و بدل نمایید.
  • بتوانید یک unwind segue اجرا نمایید (قابلیت پیمایش به عقب پیاده سازی کنید).
  • با استفاده از stack view، قالب های (layout) کارامد، انعطاف پذیر و قدرتمند ایجاد نمایید.

اضافه کردن یک segue جهت پیمایش به جلو (صفحه ی بعدی)

در حالی که داده های اپلیکیشن به صورت مورد انتظار در UI برنامه به نمایش گذاشته می شوند، اکنون زمان آن رسیده که امکان پیمایش از صفحه نمایش لیست غذاها به صفحه محتوا افزودن غذای جدید (meal scene) را فراهم نمایید. در برنامه نویسی IOS، به انتقال از یک صفحه محتوا (scene) به صفحه محتوا دیگر در اصطلاح segue گفته می شود. پیش از ایجاد یک segue، لازم است scene ها یا همان صفحات حاوی محتوای برنامه ی خود را تنظیم و پیکربندی نمایید.
در مرحله ی اول می بایست یک view controller را داخل navigation controller جاسازی نمایید. حال این سوال پیش می آید که navigation controller چیست؟ navigation controller یک کلاس فرزند و مشتق شده ی view controller با پیاده سازی اختصاصی است که امکان پیمایش به جلو و عقب بین مجموعه ای از view controller ها را مهیا می سازد. به مجموعه ای از view controller ها که توسط یک navigation controller مدیریت می شوند، navigation stack گفته می شود. اولین آیتمی که به پشته اضافه می شود، root view controller خوانده شده (view controller آغازین) و هیچگاه از روی navigation stack حذف (pop off) نمی شود.
جهت افزودن یک navigation controller به meal list scene (صفحه ی نمایش لیست غذاها با نمای جدولی)، مراحل زیر را دنبال نمایید:
1. ابتدا فایل storyboard خود، Main.storyboard را باز نمایید.
2. Table view controller (نمای جدولی) را با کلیک بر روی نوار scene dock آن، انتخاب نمایید.
پیاده سازی قابلیت پیمایش (navigation)
3. پس از انتخاب table view controller، این مسیر را طی نمایید: Editor > Embed In > Navigation Controller. محیط کاری Xcode یک navigation controller جدید به storyboard جاری اضافه کرده، آن را به عنوان صفحه محتوای آغازین این storyboard انتخاب می کند (آن را به عنوان entry point منصوب کرده) و سپس یک رابطه بین navigation controller جدید و table view controller فعلی ایجاد می کند.
پیاده سازی قابلیت پیمایش (navigation)
در سطح canvas (پس زمینه ی storyboard)، آیکونی که controller ها را به هم متصل می کند، یک رابطه است (root view controller relationship). Table view controller همان root view controller (view controller آغازین) navigation controller است که لیست غذاها را نمایش می دهد. storyboard entry point به این خاطر به navigation controller تخصیص داده شده که navigation controller نام برده در حال حاضر نقش یک ظرف (container) را برای table view controller ایفا می کند. با کمی دقت متوجه نواری در بالای نمای جدولی خود (table view) می شوید. این نوار در واقع نوار پیمایش (navigation bar) جهت راهبری در اپلیکیشن شما است. به تک تک controller های موجود در پشته یک نوار پیمایش اختصاص داده می شود که دارای دو control برای پیمایش به جلو و عقب می باشد. در گام بعدی یک دکمه به نوار پیمایش جهت راهبری به صفحه افزودن غذای جدید meal scene اضافه خواهید نمود.

تست کنید :

برنامه ی خود را اجرا کنید. در بالای table view، فضای اضافی قابل مشاهده می باشد. این فضای اضافی همان navigation bar یا نوار پیمایش است که توسط navigation controller جهت راهبری در صفحات متعدد اپلیکیشن در اختیار شما قرار می گیرد. Navigation bar پس زمینه ی خود را به بالای status bar (نوار نمایشگر وضعیت کلی دستگاه) وام می دهد تا بدین وسیله status bar دیگر با محتوای صفحه همپوشانی نداشته باشد (لبه ی آن بر روی سطر بالایی table view قرار نگیرد).

پیاده سازی قابلیت پیمایش (navigation)

تنظیم و پیکربندی Navigation Bar برای scene ها

اکنون یک عنوان (به meal list) و یک دکمه (جهت افزودن غذاهای جدید) به نوار پیمایش اضافه خواهید نمود. Navigation bar ها عنوان خود را از آن view controller ای که navigation controller در حال حاضر نمایش می دهد، می گیرند – گفتنی است که Navigation bar ها به خودی خود عنوان ندارند. عنوان مربوطه را بجای اینکه مستقیما بر روی navigation bar تنظیم کنید، با استفاده از آیتم navigation از meal list (صفحه نمایش لیست غذاها / table view controller) تنظیم خواهید نمود.
جهت تنظیم navigation bar در meal list (یا لیست نمایش غذاهای جدول)، مراحل زیر را به ترتیب دنبال نمایید:
1. بر روی navigation bar در صفحه محتوای نمایش لیست غذاها (meal list scene) دوبار کلیک نمایید.
پیاده سازی قابلیت پیمایش (navigation)
یک مکان نما به نمایش درآمده و به شما اجازه ی درج متن جدید را می دهد.
2. واژه ی Your Meals را وارد نموده، سپس کلید Return را جهت ذخیره سازی تغییرات فشار دهید.
پیاده سازی قابلیت پیمایش (navigation)
3. کادر Object library را باز نمایید (برای این منظور کافی است مراحل روبرو را دنبال نمایید: View > Utilities > Show Object Library).
4. در کادر object library، آبجکت Bar Button Item را جستجو نمایید.
5. حال آبجکت مزبور را از کادر object library کشیده و در سمت راست نوار پیمایش در meal list scene جایگذاری نمایید.
یک دکمه به نام item در جایی که آبجکت Bar Button را در آن قرار دادید نمایان می شود.
پیاده سازی قابلیت پیمایش (navigation)
6. دکمه ی item را انتخاب نموده، سپس کادر Attribute inspector را باز نمایید.
7. در کادر Attribute inspector، گزینه ی Add را از منوی pop-up جنب آپشن System item انتخاب نمایید. خواهید دید که ظاهر دکمه به یک علامت (+) تغییر می کند.
پیاده سازی قابلیت پیمایش (navigation)

تست کنید :

برنامه را اجرا کنید. در حال حاضر نوار پیمایش می بایست یک عنوان داشته و یک دکمه ی (+) برای کاربر به نمایش بگذارد. البته دکمه ی ذکر شده در زمان حاضر کار خاصی انجام نمی دهد. در گام بعدی رفتار آن را پیاده سازی خواهید نمود.

پیاده سازی قابلیت پیمایش (navigation)

شما می خواهید دکمه ی (+)، صفحه ی افزودن غذای جدید به لیست غذاهای جاری را فراخوانی کرده و برای کاربر به نمایش بگذارد. برای این منظور، رفتاری برای دکمه تعریف می کنید که طی آن یک انتقال به صفحه ی دیگر از برنامه رخ می دهد (با کلیک بر روی دکمه یک segue رخ داده و صفحه ی افزودن غذای جدید پدیدار شود).
جهت تنظیم و پیکربندی دکمه ی Add در meal scene مراحل زیر را دنبال نمایید:
1. در سطح canvas دکمه ی (+) را انتخاب نمایید.
2. دکمه را با اشاره گر موس کشیده و در سطح meal scene جایگذاری نمایید.
پیاده سازی قابلیت پیمایش (navigation)
یک منوی میانبر با عنوان Action Segue در مکانی که کشیدن آیتم را در آن متوقف کردید، پدیدار می شود.
پیاده سازی قابلیت پیمایش (navigation)
منوی Action Segue حاوی تعدادی گزینه است که از طریق آن ها می توانید نوع segue (انتقال) از صفحه نمایش لیست غذاها (meal list) به صفحه ی افزودن غذای جدید (new meal view controller) را زمانی که کاربر بر روی دکمه ی مورد نظر کلیک می کند، تعیین نمایید.
3. گزینه ی show را از منوی Action Segue انتخاب نمایید.
محیط کاری Xcode انتقال از صفحه ی نمایش لیست غذاها (meal list) به صفحه ی افزودن غذای جدید (meal scene) را به سبک انتخاب شده (show segue) پیکربندی نموده، تنظیمات لازم جهت نمایش meal scene در یک navigation controller را انجام می دهد –navigation bar را در Interface Builder می بینید.
پیاده سازی قابلیت پیمایش (navigation)

تست کنید :

برنامه را اجرا نمایید. با توجه به کدی که برای برنامه نوشته اید، باید بتوانید بر روی دکمه ی (+) کلیک کرده و به صفحه محتوای افزودن غذای جدید پیمایش نمایید. به این خاطر که برای انتقال از یک صفحه محتوا به صفحه محتوای دیگر از show segue استفاده می کنید، پیمایش به عقب (backward navigation) به صورت آماده پیاده سازی شده است و دکمه ی پیمایش به عقب جهت بازگشت به صفحه نمایش لیست غذاها به صورت خودکار در meal scene (صفحه ی افزودن غذای جدید) به نمایش در می آید.
پیاده سازی قابلیت پیمایش (navigation)
پیمایش به سبک push (قرار دادن محتوای جدید بر روی پشته ای از view controller های جاری) که با انتخاب show segue در اختیار شما قرار می گیرد، به صورت مورد انتظار کار می کند – اما این سبک پیمایش به صفحه ی دیگر آنچه که شما به هنگام افزودن آیتم جدید برای برنامه ی جاری نیاز دارید، نیست. پیمایش به سبک push بیشتر مناسب رابط های کاربری drill-down (راهبری یا پیمایش از بالا به پایین) می باشد که در آن می خواهید اطلاعاتی را در خصوص انتخاب های کاربر در UI نمایش دهید. برای اضافه کردن آیتم جدید معمولا باید یک نوع عملیات modal انجام شود – صفحه ای مجزا به صورت شناور باز می شود و کاربر در آن عمل خاصی را انجام می دهد، متعاقبا از آن scene یا صفحه به navigation اصلی باز می گردد. روش صحیح و مناسب برای این نوع نمایش یک modal segue است. در این نوع segue یک view controller، view controller دیگری را به عنوان فرزند خود به نمایش گذاشته و از کاربر انتظار دارد که فعل خاصی را بر روی آن انجام دهد (برای مثال متنی را وارد کند)، پس از دریافت واکنش مورد نظر از جانب کاربر، او را به جریان عادی برنامه بر می گرداند.
بجای حذف segue جاری و ایجاد یک segue جدید، کافی است سبک انتقال (segue style) از صفحه به صفحه ی دیگر را از طریق کادر Attribute inspector تغییر دهید. می توانید attribute های یک segue را مانند دیگر آیتم های قابل گزینش در storyboard، از طریق کادر Attribute inspector ویرایش نمایید.
جهت تغییر سبک انتقال از یک صفحه به صفحه ی دیگر (segue style)، مراحل زیر را دنبال نمایید:
1. ابتدا segue (جهت انتقال) از صفحه نمایش لیست غذاها (meal list scene) به صفحه ی افزودن غذای جدید (meal scene) را انتخاب نمایید.
پیاده سازی قابلیت پیمایش (navigation)
2. در کادر Attribute inspector، گزینه ی Present Modally را از منوی pop-up، جنب گزینه ی Segue انتخاب نمایید.
3. داخل کادر Attribute inspector، واژه ی AddItem را در فیلد Identifier تایپ نمایید. بعده ها به identifier یا اسم انتخاب شده برای segue مورد نظر جهت دسترسی و اشاره به آن احتیاج خواهید داشت.
با انجام مراحل عنوان شده در بالا، modal view controller به navigation stack اضافه نمی شود. به همین خاطر هم این آیتم نوار پیمایش (navigation bar) خود را از navigation controller مربوط به meal list وام نمی گیرد. اما شما لازم دارید که با اضافه شدن نوار پیمایش برای کاربر قابلیت پیمایش بین صفحات را فراهم نموده و در واقع یک نوع پیوستگی بصری را در برنامه ی خود بوجود بیاورید.
به منظور اینکه meal list به هنگام نمایش به صورت modal دارای نوار پیمایش باشد، کافی است آن را در navigation controller ویژه ی خود جاسازی نمایید (بگنجانید).
به منظور افزودن navigation controller به صفحه ی افزودن غذای جدید (meal scene)، کافی است مراحل زیر را دنبال نمایید:
1. Meal scene را با کلیک بر روی scene dock مربوطه ی آن، انتخاب نمایید.
پیاده سازی قابلیت پیمایش (navigation)
2. پس از انتخاب view controller، مراحل رو به رو را دنبال نمایید: Editor > Embed In > Navigation Controller.
درست مانند قبل، Xcode یک navigation controller اضافه نموده و نوار پیمایش را در بالای meal scene (صفحه ی افزودن غذای جدید) به نمایش می گذارد. در گام بعدی، این نوار را طوری تنظیم می کنید که علاوه بر یک عنوان، دو دکمه نیز جهت Save و Cancel به صفحه محتوای جاری (scene) اضافه کند. بعده ها این دو کنترل دکمه را به action های مربوطه (متدها یا عملیاتی که به محض کلیک بر روی دکمه های نام برده فراخوانی و اجرا می شوند) متصل خواهید نمود.
پیاده سازی قابلیت پیمایش (navigation)
جهت ایجاد و تنظیم نوار پیمایش در meal scene، مراحل زیر را به ترتیب دنبال نمایید:
1. بر روی navigation bar یا نوار پیمایش در meal scene دابل کلیک کنید.
پیاده سازی قابلیت پیمایش (navigation)
با کلیک بر روی نوار پیمایش، یک مکان نما پدیدار شده که به شما اجازه ی درج متن را می دهد.
2. واژه ی New Meal را تایپ نموده و سپس کلید Return را فشار دهید.
3. حال یک آبجکت Bar Button Item از کادر Object Library انتخاب نمایید و آن را با اشاره گر موس به ناحیه ی سمت چپ نوار پیمایش مورد نظر کشیده (داخل meal scene)، در آنجا جایگذاری کنید.
4. داخل کادر Attribute inspector، از فیلد System Item، گزینه ی Cancel را انتخاب نمایید. می بینید که متن دکمه به Cancel تغییر می کند.
پیاده سازی قابلیت پیمایش (navigation)
5. اکنون یک Bar Button Item دیگر از کادر Object library انتخاب کرده و به ناحیه ی سمت راست نوار پیمایش مورد نظر در meal scene بکشید و در آنجا جایگذاری کنید.
6. داخل کادر Attribute inspector، از فیلد System Item، گزینه ی Save را انتخاب نمایید. می بینید که متن دکمه ی مورد نظر به Save تغییر می کند.
پیاده سازی قابلیت پیمایش (navigation)

تست کنید :

برنامه ی خود را اجرا نمایید. حال بر روی دکمه ی Add کلیک کنید. می بینید که همچنان meal scene در حال نمایش می باشد، اما این بار دیگر دکمه ای جهت بازگشت به meal list وجود ندارد – بجای آن دو دکمه ی Cancel و Save را مشاهده می کنید. همان طور که می دانید دو دکمه نام برده هنوز به هیچ action و عملیاتی وصل نیستند، از اینرو با کلیک بر روی آن ها اتفاق خاصی رخ نمی دهد. به زودی به این دکمه ها قابلیت ذخیره/عدم ذخیره ی غذای جدید و همچنین بازگرداندن کاربر به صفحه ی نمایش لیست غذاها (meal list scene) را اعطا خواهید کرد.
پیاده سازی قابلیت پیمایش (navigation)

تکمیل ظاهر برنامه (UI) با بهره گیری موتور نمایش/مدیریت چیدمان المان ها Auto Layout

UI اصلی و اولیه ی اپلیکیشن خود را چندی پیش طراحی کردید. اما از زمان ایجاد ظاهر اصلی برنامه تا کنون، همان طور که طی آموزش های پیشین شاهد آن بودید، تغییرات زیادی رخ داده. در اینجا تغییرات بیشتری را به layout (قالب و طرح کلی) برنامه وارد نخواهید کرد بلکه صرفا با بهره گیری از موتور نمایش و مدیریت چیدمان المان های UI، ابزار Auto layout محیط کاری Xcode، المان های رابط کاربری که به صورت پشته بر روی هم چیده شده اند ( stack view) را تنظیم نموده و از نمایش صحیح آن ها برای کاربر اطمینان حاصل می کنید.
جهت بروز رسانی layout و چیدمان کلی stack view، مراحل زیر را گام به گام دنبال نمایید:
1. داخل meal scene، با کلیک بر روی ناحیه ی آبی کم رنگ، stack view جاری را انتخاب نمایید.
پیاده سازی قابلیت پیمایش (navigation)
یا می توانید Stack View را از کادر Outline view انتخاب نمایید.
2. در گوشه ی پایین، سمت راست canvas، منوی Resolve Auto Layout Issues را باز نمایید.
پیاده سازی قابلیت پیمایش (navigation)
3. از منوی مذکور، گزینه ی Update Constraints را انتخاب نمایید.
پیاده سازی قابلیت پیمایش (navigation)
4. المان ها در جای اولیه ی خود باقی می مانند، اما stack view اکنون بجای خط حاشیه ی بالای صفحه (top margin)، به نوار پیمایش viewمورد نظر متصل شده است.
Constraint های meal scene و UI اکنون ظاهری مانند زیر خواهد داشت:
پیاده سازی قابلیت پیمایش (navigation)
تست کنید : برنامه ی خود را اجرا کنید. فیلد درج متن (text field) و کنترل امتیازدهی به غذا (rating control) هم اکنون می بایست نزدیکتر به نوار پیمایش باشند.
پیاده سازی قابلیت پیمایش (navigation)

ذخیره نمودن غذاهای جدید در لیست غذاها (Meal List)

گام بعدی در افزودن قابلیت به برنامه ی FoodTracker و تکمیل امکانات آن، پیاده سازی امکان افزودن غذای جدید به لیست غذاهای برنامه است. به طور مشخص شما در نظر دارید، زمانی که کاربر اسم غذا، امتیاز و عکس دلخواه برای آن را در meal scene وارد کرده و دکمه ی Save را کلیک کرد، MealViewController (صفحه محتوای افزودن غذای جدید/meal scene) یک آبجکت Meal با اطلاعات مربوطه ایجاد (configure) کند و سپس آن اطلاعات را به MealTableViewController جهت نمایش در صفحه ی لیست غذاها (meal list) پاس دهد.
برای نیل به این هدف، ابتدا یک property به نام Meal در MealViewController تعریف می کنید.
به منظور افزودن متغیر Meal به MealViewController، مراحل زیر را دنبال نمایید:
1. فایل MealViewController.swift را باز کنید.
2. در زیر متغیر (outlet) ratingControl در فایل MealViewController.swift، متغیر (property) زیر را وارد نمایید:

/*
This value is either passed by `MealTableViewController` in `prepareForSegue(_:sender:)`
or constructed as part of adding a new meal.
*/
var meal: Meal?

این دستور یک property در MealViewController تعریف می کند که این property یک Meal از نوع optional است. بدین معنی که می تواند در هر برهه ای از زمان هیچ مقداری نداشته و به اصطلاح nil باشد.
قاعدتا شما تنها زمانی می خواهید آبجکت Meal ساخته شده و پاس داده شود که دکمه ی Save کلیک شده باشد. برای اینکه بتوان تشخیص داد چه زمانی این اتفاق رخ داده (دکمه توسط کاربر فشرده شده)، دکمه ی Save را در قالب یک outlet (با افزودن خصیصه ی @IBAction) در فایل MealViewController.swift تعریف می کنید.
به منظور متصل کردن دکمه ی Save به کد موجود در MealViewController، مسیر زیر را طی نمایید:
1. فایل storyboard را باز نمایید.
2. بر روی دکمه ی Assistant در نوار ابزار Xcode کلیک نموده تا ویرایشگر کمکی (assistant editor) محیط به نمایش درآید.
پیاده سازی قابلیت پیمایش (navigation)
3. در صورت نیاز به فضای کاری بیشتر، کادر Project navigator و Utility area را با کلیک بر روی دکمه های مربوطه در نوار ابزار Xcode، پنهان نمایید.
پیاده سازی قابلیت پیمایش (navigation)
4. در Storyboard، دکمه ی Save را انتخاب نمایید.
5. دکمه ی Save را با اشاره گر موس (و فشردن کلید control) بر روی ناحیه ی ویرایش کد (داخل ویرایشگر کمکی و فایل MealViewController.swift) کشیده و آن را در زیر متغیر ratingControl جایگذاری نمایید.
پیاده سازی قابلیت پیمایش (navigation)
6. داخل کادر محاوره ای که نمایان می شود، واژه ی saveButton را در کادر Name وارد نمایید. لازم به انجام تنظیمات دیگری نیست.
پیاده سازی قابلیت پیمایش (navigation)
7. حال دکمه ی Connect را کلیک کنید.

تعریف قابلیت پیمایش به عقب (unwind Segue)

اکنون کاری که باید انجام دهید عبارت است از ارسال آبجکت Meal به MealTableViewController، زمانی که کاربر دکمه ی Save را فشار می دهد و دور انداختن یا حذف آن به هنگام کلیک کاربر بر روی دکمه ی Cancel. در هر دو مورد صفحه ی مورد نمایش باید از meal scene (صفحه ی افزودن غذای جدید) به meal list scene (صفحه نمایش لیست غذاها) تغییر کند.
برای انجام این کار می بایست از یک unwind segue بهره بگیرید. Unwind segue یک یا چند segue را به عقب پیمایش کرده و کاربر را به یک نمونه از view controller باز می گرداند. به عبارت دیگر شما به وسیله ی unwind segue، پیمایش به عقب (reverse navigation) یا صفحات قبلی برنامه را پیاده سازی می کنید.
هر زمان که یک segue فعال می شود، به دنبال آن مکانی در قالب یک متد برای شما ایجاد می شود که می توانید در بدنه ی آن کد خود را اضافه نموده و انتظار اجرای آن را داشته باشید. اسم این متد prepareForSegue(_:sender:) بوده و این امکان را به شما می دهد تا داده های مورد نیاز را ذخیره کنید و هر گونه عملیات cleanup لازم را در source view controller ( view controller مبدا) که segue از آن آغاز می شود، انجام دهید. برای رسیدن به این هدف، متد ذکر شده را در MealViewController پیاده سازی خواهید کرد.
به منظور پیاده سازی متد prepareForSegue(_:sender:) در MealViewController، مراحل زیر را دنبال نمایید:
1. با کلیک بر روی دکمه ی Standard (اشاره شده در تصویر زیر)، ویرایشگر اصلی (Standard editor) محیط را باز نمایید.
پیاده سازی قابلیت پیمایش (navigation)
2. فایل MealViewController.swift را باز کنید.
3. در فایل MealViewController.swift، بالای بخش // MARK: Actions، کد زیر را درج نمایید:

// MARK: Navigation

4. این خط صرفا یک comment است که شرحی در خصوص مورد کاربرد کد ارائه داده و به شما (یا هر شخص دیگری که کد شما را می خواند) اعلان می کند که متد درج شده در زیر آن مربوط به قابلیت پیمایش (navigation flow) در برنامه می باشد.

// MARK: Navigation

5. در زیر comment، تعریف متد را به صورت زیر وارد نمایید:

// This method lets you configure a view controller before it's presented.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
}

6. داخل بدنه ی متدprepareForSegue(_:sender:) ، دستور شرطی زیر را درج نمایید:

if saveButton === sender {
}

این کد با استفاده از عملگر "===" بررسی می کند آیا آبجکت مورد اشاره ی متغیر (outlet) saveButton همان object instance/نمونه کلاس sender (فراخواننده ی action) است یا خیر (هر دو به یک نمونه کلاس اشاره دارند یا خیر). در صورتی که این امر صادق بود، دستور if اجرا خواهد شد.
داخل ساختمان if، کد زیر را وارد نمایید:

let name = nameTextField.text ?? ""
let photo = photoImageView.image
let rating = ratingControl.rating

این کد سه ثابت از property یا خصوصیت های text، selected image و rating موجود در scene مورد نظر ایجاد می کند. حال توجه خود را به عملگر "??" در خط name جلب نمایید. این عملگر برای این استفاده شده که بررسی کند اگر متغیر از نوع optional مقداری داشت، آن مقدار را برگرداند و در غیر این صورت یک مقدار پیش فرض را بازگردانی نماید. nameTextField.text (یک متغیر optional است چرا که text field می تواند متن داشته یا نداشته باشد) یک مقدار برمی گرداند. در اینجا عملگر "??"، مقدار بازگشتی توسط nameTextField.text را استخراج نموده (unwrap) و در دسترس قرار می دهد. اگر مقدار بازگشتی یک رشته ی مجاز بود، آن را برمی گرداند و در غیر این صورت، مقدار پیش فرض که همان رشته ی تهی ("") است را در خروجی بازگردانی می کند.
7. داخل ساختمان دستور شرطی if، کد زیر را وارد نمایید:

// Set the meal to be passed to MealTableViewController after the unwind segue.
meal = Meal(name: name, photo: photo, rating: rating)

این کد، متغیر meal را پیش از اجرای segue، با مقادیر مناسب تنظیم می کند.
در حال حاضر، پیاده سازی متد prepareForSegue(_:sender:) شما باید به صورت زیر باشد:

// This method lets you configure a view controller before it's presented.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if saveButton === sender {
let name = nameTextField.text ?? ""
let photo = photoImageView.image
let rating = ratingControl.rating
// Set the meal to be passed to MealTableViewController after the unwind segue.
meal = Meal(name: name, photo: photo, rating: rating)
}
}

گام بعدی در پیاده سازی پیمایش به عقب (ایجاد یک unwind segue)، افزودن یک action method به destination view controller (view controller مقصد) است. این متد باید با attribute یا خصیصه ی IBAction علامت گذاری شده و به عنوان پارامتر خود یک segue (UIStoryboardSegue) را بپذیرد. از آنجایی که شما می خواهید به صفحه ی نمایش لیست غذاها برگردید (meal list scene)، بایستی متدی با این فرمت را به فایل MealTableViewController.swift اضافه نمایید.
داخل بدنه ی این متد، منطقی را که غذای جدید (ارسال شده از MealViewController که source view controller هست) را به داده های جاری لیست غذاها افزوده و سپس یک سطر جدید به نمای جدولی (table view) در صفحه نمایش لیست غذاها (meal list scene) اضافه می کند، پیاده سازی خواهید نمود.
به منظور افزودن action method به کد موجود در فایل MealTableViewController، مراحل زیر را دنبال نمایید:
1. فایل MealTableViewController.swift را باز کنید.
2. در فایل MealTableViewController.swift، درست قبل از آخرین ({)، دستور زیر را اضافه نمایید:

@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
}

3. داخل بدنه ی متد unwindToMealList(_:)، دستور شرطی if را اضافه نمایید:

    if let sourceViewController = sender.sourceViewController as? MealViewController, meal = sourceViewController.meal {
}

در شرط تعریف شده توسط این دستور if، اتفاقات زیادی می افتد. این کد از عملگر (as?) برای downcast و تبدیل آزمایشی source view controller از segue مورد نظر به نوع MealViewController بهره می گیرد. انجام downcast ضروری است چرا که sender.sourceViewController از جنس کلاس UIViewController است، اما شما مجبورید که با MealViewController کار کنید (downcast عبارت است از تبدیل یک آبجکت به یکی از کلاس های مشتق شده از آن).
عملگر مورد نظر یک مقدار optional برمی گرداند که در صورت ناموفق بودن downcast آن مقدار nil خواهد بود. اما چنانچه downcast با موفقیت صورت پذیرفت، آنگاه کد view controller مورد نظر را به ثابت (constant) محلی sourceViewController تخصیص می دهد و همچنین بررسی می کند که متغیر meal در sourceViewController دارای مقدار nil هست یا خیر. اگر متغیر meal دارای مقدار و به اصطلاح non-nil بود، کد مورد نظر مقدار آن متغیر (property) را به ثابت محلی meal اختصاص داده و دستور داخل بدنه ی if را اجرا می کند.
در صورتی که downcast با شکست مواجه شده یا متغیر تعریف شده در sourceViewController دارای مقدار nil بود، آنگاه شرط صادق نبوده (نتیجه ی آن false بوده) و به تبع آن دستور شرطی if اجرا نمی شود.
4. در بدنه ی دستور if، کد زیر را درج نمایید:

// Add a new meal.
let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)

این کد محل جدید قرار گیری خانه ی جدول که نمایشگر (حاوی اطلاعات) غذای جدید است را در نمای جدولی (table view) محاسبه نموده و سپس آن را در ثابت (constant) محلی به نام newIndexPath ذخیره می کند.
5. داخل بدنه ی if، در زیر خط قبلی، کد زیر را اضافه نمایید:

meals.append(meal)

این دستور، غذای جدید را به لیست غذاهای جاری، کپسوله سازی (ذخیره) شده در data model، اضافه می کند.
6. حال دستور زیر را در زیر خط قبلی، داخل ساختمان if، درج نمایید:

tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)

این دستور فرایند اضافه شدن سطر جدید به نمای جدولی (table view) را در خانه ای که حاوی اطلاعات مربوط به غذای جدید می باشد، با انیمیشن به اجرا در می آورد. پارامتر .Bottom سبب می شود که سطر جدید از پایین صفحه به آن اضافه شود.
به زودی این متد را با پیاده سازی پیچیده تری خواهید نوشت. در حال حاضر بدنه ی متد unwindToMealList(_:) می بایست به شکل زیر باشد:

@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? MealViewController, meal = sourceViewController.meal {
// Add a new meal.
let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)
meals.append(meal)
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
}
}

اکنون می بایست unwind segue را که قرار است action method مورد نظر را فراخوانی کرده و سبب اجرای آن شود، ایجاد نمایید.
جهت متصل کردن دکمه ی Save به متد unwindToMealList، مراحل زیر را دنبال نمایید:
1. ابتدا Storyboard را باز نمایید.
2. در سطح canvas، کلید control را نگه داشته و با اشاره گر موس دکمه ی Save را به سمت آیتم Exit در بالای صفحه محتوای جاری (meal scene) بکشید و در آنجا جایگذاری نمایید.
پیاده سازی قابلیت پیمایش (navigation)
یک منو در مکانی که دکمه ی Save را در آن جایگذاری نمودید، پدیدار می شود.
پیاده سازی قابلیت پیمایش (navigation)
3. گزینه ی unwindToMealList: را از منوی میانبر انتخاب نمایید.
اکنون، زمانی که کاربران بر روی دکمه ی Save کلیک می کنند، برنامه کاربر را به صفحه نمایش لیست غذاها باز می گرداند. این کار با فراخوانی متد unwindToMealList(_:) صورت می پذیرد.

تست کنید »:

برنامه را اجرا نمایید. اکنون زمانی که بر روی دکمه ی (+) کلیک می کنید، سپس یک غذای جدید ایجاد نموده و به دنبال آن دکمه ی Save را فشار می دهید، باید غذای جدید را در لیست نمایش غذاها مشاهده نمایید. مهم: در صورت عدم مشاهده ی متد unwindToMealList در منوی میانبر، باید اطمینان حاصل نمایید که signature (اسم، تعداد و نوع پارامترهای ورودی) متد کاملا صحیح است.

@IBAction func unwindToMealList(sender: UIStoryboardSegue)

غیر فعال نمودن قابلیت ذخیره (دکمه ی Save) زمانی که کاربر اسم آیتم را وارد نکند

حالا اگر کاربر سعی کند بدون وارد کردن اسم غذا، آن را ذخیره کند، چه اتفاقی رخ می دهد؟ از آنجایی که متغیر meal در MealViewController از نوع optional می باشد و همچنین شما متد سازنده (initializer) خود را طوری تنظیم کردید که در صورت عدم وجود اسم برای غذا (در مقداردهی اولیه) با شکست مواجه شود، آبجکت Meal ایجاد نشده و به لیست غذاها اضافه نمی شود – شما هم دقیقا همین را انتظار دارید.
شما می توانید این کد را کمی پیچیده تر نمایید: برای مثال می توانید با غیر فعال کردن دکمه ی Save، هنگامی که کاربر در حال وارد کردن اسم برای غذای جدید است، مانع از این شوید که کاربر سهوا بدون وارد کردن اسم غذا، آن را ذخیره کند یا بررسی کنید اسم وارد شده برای غذا کاملا صحیح است و بعد اجازه ی بستن صفحه کلید را به کاربر بدهید.
جهت غیر فعال سازی دکمه ی Save، زمانی که اسمی برای آن وارد نشده، مراحل زیر را دنبال نمایید:
1. در فایل MealViewController.swift، ابتدا بخش // MARK: UITextFieldDelegate را پیدا کنید. یادآور می شویم که با استفاده از ابزار functions menu می توانید به سرعت به بخش مورد نظر در کد برنامه پیمایش کنید (بپرید). برای دسترسی به این ابزار کافی است بر روی اسم فایل در بالای ناحیه ی ویرایش (editor area) کلیک نمایید.
2. در این بخش، یک متد UITextFieldDelegate دیگر اضافه نمایید.

func textFieldDidBeginEditing(textField: UITextField) {
// Disable the Save button while editing.
saveButton.enabled = false
}

متد textFieldDidBeginEditing زمانی صدا خورده می شود که وضعیت ویرایش شروع شده (editing session) یا زمانی که صفحه کلید به نمایش در می آید. این کد دکمه ی Save را هنگامی که کاربر در حال ویرایش متن داخل text field است، غیر فعال می سازد.
3. در زیر متد textFieldDidBeginEditing(_:)، متد دیگری به صورت زیر اضافه نمایید:

                                                                                                                                                                                                                                                                                                         ">
func checkValidMealName() {
// Disable the Save button if the text field is empty.
let text = nameTextField.text ?? ""
saveButton.enabled = !text.isEmpty
}

این متد، یک تابع کمکی است که در صورت تهی بودن text field دکمه ی Save را غیر فعال می سازد.
4. متد textFieldDidEndEditing(_:) را پیدا کنید:

                                                                                                                                                                                                                                                                                         ">
func textFieldDidEndEditing(textField: UITextField) {
}

بدنه ی این متد در حال حاضر می بایست تهی باشد.
5. دستورات زیر را در آن وارد نمایید:

                                                                                                                                                                                                                                                                                               ">
checkValidMealName()
navigationItem.title = textField.text

اولین خط با فراخوانی متد checkValidMealName() بررسی می کند آیا text field داخل خود متنی دارد یا خیر و در صورت وجود متن در فیلد مزبور، دکمه ی Save را فعال می سازد. خط دوم عنوان صفحه (title صفحه محتوا یا scene جاری) را برابر متن وارد شده در text field قرار می دهد.
6. حال متد viewDidLoad() را در کد پیدا کنید:

                                                                                                                                                                                                                                                                                               ">
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
}

7. متد checkValidMealName() را فراخوانی نموده تا مطمئن شوید دکمه ی Save تا زمانی که کاربر یک اسم مجاز در text field وارد نکرده، غیر فعال می ماند:

                                                                                                                                                                                                                                                                                               ">
// Enable the Save button only if the text field has a valid Meal name.
checkValidMealName()
در حال حاضر بدنه ی متد viewDidLoad() می بایست ظاهری مشابه زیر داشته باشد:
                                                                                                                                                                                                                                                                                               ">
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
// Enable the Save button only if the text field has a valid Meal name.
checkValidMealName()
}
متد textFieldDidEndEditing(_:) نیز می بایست دارای پیاده سازی زیر باشد:
                                                                                                                                                                                                                                                                                               ">
func textFieldDidEndEditing(textField: UITextField) {
checkValidMealName()
navigationItem.title = textField.text
}
تست کنید :

برنامه ی خود را اجرا کنید. حال هنگامی که شما بر روی دکمه ی (+) کلیک می کنید، دکمه ی Save غیر فعال شده و تا زمانی که یک اسم مجاز در text field وارد نکرده و صفحه کلید را معاف نکرده باشید، این دکمه غیر فعال می ماند.
پیاده سازی قابلیت پیمایش (navigation)

پیاده سازی قابلیت لغو فرایند اضافه و ذخیره کردن آیتم جدید (پیاده سازی رفتار مربوط به دکمه ی Cancel)

یک کاربر ممکن است مایل باشد نظر خود را در مورد افزودن یک غذای جدید به لیست تغییر داده و آن را لغو کند. در واقع بدون افزودن آیتم جدید و ذخیره ی آن، به صفحه ی meal list (لیست غذاها) بازگردد. برای این منظور می بایست رفتار دکمه ی Cancel را پیاده سازی نمایید.
به منظور ایجاد و پیاده سازی یک action method که به دکمه ی Cancel متصل باشد، مراحل زیر را دنبال نمایید:
1. ابتدا storyboard را باز نمایید.
2. بر روی دکمه ی Assistant در نوار ابزار Xcode کلیک کرده تا ویرایشگر کمکی محیط (assistant editor) باز شود.
پیاده سازی قابلیت پیمایش (navigation)
3. داخل storyboard، دکمه ی Cancel را انتخاب نمایید.
4. بر روی دکمه ی Cancel کلیک کرده، کلید control را نگه دارید. سپس آن را از سطح canvas به ناحیه ی ویرایش کد در سمت راست محیط (داخل فایل MealViewController.swift)، زیر خط // MARK: Navigation بکشید و در آنجا جایگذاری نمایید.
پیاده سازی قابلیت پیمایش (navigation)
5. در کادر محاوره ای که نمایان می شود، از فیلد Connection، گزینه ی Action را انتخاب نمایید.
6. داخل فیلد Name، واژه ی cancel را وارد نمایید.
7. از فیلد Type، گزینه ی UIBarButtonItem را انتخاب نمایید.
لازم به اعمال تغییرات دیگری در این کادر محاوره ای نیست. در حال حاضر این کادر می بایست ظاهری مشابه زیر داشته باشد:
پیاده سازی قابلیت پیمایش (navigation)
8. دکمه ی Connect را کلیک نمایید.
Xcode خود کد لازم را ویژه ی action مورد نظر به فایل MealViewController.swift اضافه می کند.

                                                                                                                                                                                                                                                                                               ">
@IBAction func cancel(sender: UIBarButtonItem) {
}
9. داخل بدنه ی متد cancel(_:)، این دستور را اضافه نمایید:
                                                                                                                                                                                                                                                                                               ">
dismissViewControllerAnimated(true, completion: nil)

این کد صفحه ی افزودن غذای جدید (meal scene) را بدون ذخیره ی اطلاعات جدید، بسته و کاربر را به صفحه ی نمایش لیست غذاها (meal list scene) هدایت می کند.
کد موجود در ساختمان متد cancel(_:) هم اکنون می بایست به صورت زیر باشد:

                                                                                                                                                                                                                                                                                               ">
@IBAction func cancel(sender: UIBarButtonItem) {
dismissViewControllerAnimated(true, completion: nil)
}
تست کنید :

برنامه ی خود را اجرا نمایید. اکنون زمانی که شما دکمه ی (+) را فشار داده و سپس بجای دکمه ی Save بر روی Cancel کلیک می کنید، برنامه می بایست بدون ذخیره ی اطلاعات یک آیتم جدید، شما را به صفحه ی meal list هدایت کند.

  • 1355
  •    1110
  • تاریخ ارسال :   1395/08/06

دانلود PDF دانشجویان گرامی اگر این مطلب برای شما مفید بود لطفا ما را در GooglePlus محبوب کنید
رمز عبور: tahlildadeh.com یا www.tahlildadeh.com
ارسال دیدگاه نظرات کاربران
شماره موبایل دیدگاه
عنوان پست الکترونیک

ارسال

آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

تمامی حقوق این سایت متعلق به آموزشگاه تحلیل داده می باشد .