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

آموزش Edit و Delete درSwift

 آموزش Edit و Delete درSwift پیاده سازی قابلیت حذف و ویرایش

در این مبحث رفتاری به برنامه اضافه می کنید که به کاربر اجازه می دهد اطلاعات مربوط به غذاهای فهرست شده در برنامه ی FoodTracker را ویرایش کرده و در صورت لزوم حذف نماید.

 آموزش Edit و Delete درSwift آنچه خواهید آموخت

  1. فرق بین پیمایش (navigation) به صورت push و پیمایش به صورت modal را درک کنید.
  2. View controller ها را با توجه به سبک نمایش آن ها (presentation style)، از نمایشگر پنهان نمایید.
  3. بدانید برای downcast (تبدیل نوع از کلاس والد به یکی از کلاس های مشتق شده از آن) چه موقع از کدام عملگر تبدیل نوع (type cast operator) بهره بگیرید.
  4. با بهره گیری از optional binding شرایط پیچیده را بررسی کنید.
  5. با استفاده از اسم تخصیص داده شده به segue ها (segue identifier)، تشخیص دهید کدام segue در حال اجرا است.

 آموزش Edit و Delete درSwift پیاده سازی امکان ویرایش غذاهای جاری

در حال حاضر، برنامه ی FoodTracker به کاربران خود این امکان را می دهد تا یک آیتم جدید را به لیست غذاها اضافه کنند. در مرحله ی بعدی، قابلیت ویرایش اطلاعات غذای جاری را به کاربر اعطا خواهید نمود.
در این بخش شما به کاربر این امکان را می دهید تا بر روی یک خانه از جدول کلیک کرده و به مجرد کلیک نسخه ای از صفحه محتوای افزودن غذای جدید (meal scene) را مشاهده کند که از قبل با اطلاعات مربوط به یک غذا پر شده است. کاربر تغییراتی را اعمال کرده، سپس بر روی دکمه ی Save جهت بروز رسانی و بازنویسی اطلاعات آیتم جاری در لیست غذاها، کلیک می کند.
جهت تنظیم خانه ی جدول برای ویرایش و بروز رسانی اطلاعات، مراحل زیر را دنبال نمایید:
1. ابتدا با کلیک بر روی دکمه ی Standard (اشاره در تصویر زیر)، ویرایشگر اصلی (standard editor) محیط کاری Xcode را باز نمایید.

آموزش Edit و Delete درSwift

2. حال storyboard، فایل Main.storyboard را باز نمایید.
3. در سطح canvas، خانه ی جدول (table view cell) را با کلیک بر روی آن، انتخاب نمایید.
4. کلید control را نگه دارید و سپس با اشاره گر موس خانه ی جدول را به meal scene یا صفحه ی افزودن غذای جدید بکشید.


آموزش Edit و Delete درSwift

یک منوی میانبر (shortcut menu) با عنوان Selection Segue در مکانی که آیتم مورد نظر را در آنجا جایگذاری کردید، پدیدار می شود.


آموزش Edit و Delete درSwift

5. از منوی مزبور، گزینه ی show را انتخاب نمایید.
6. Navigation controller موجود بین دو صفحه محتوای meal list (نمایش لیست غذاها) و meal scene (صفحه محتوای افزودن غذای جدید) به سمت پایین کشیده تا segue (انتقال) بین دو scene را مشاهده نمایید.


آموزش Edit و Delete درSwift

در صورت تمایل، می توانید با اعمال همزمان کلیدهای Command و (-) تصویر را کوچک نمایید.
7. در سطح canvas، با کلیک بر روی segue جدید، آن را انتخاب نمایید.


آموزش Edit و Delete درSwift

8. داخل کادر Attribute inspector، واژه ی ShowDetail را به عنوان اسم و شناسه ی segue مورد نظر در فیلد identifier وارد نمایید. کلید Return را فشار دهید.


آموزش Edit و Delete درSwift

اکنون زمانی که این segue اجرا می شود، همزمان view controller مربوط به meal scene (صفحه ی افزودن آیتم جدید) بر روی همان navigation stack یا مجموعه view controller هایی که meal list (صفحه محتوای نمایش لیست غذاها) در حال حاضر عضو آن است، به سبک push قرار می گیرد.
تست کنید: برنامه ی خود را اجرا کنید. در صفحه ی نمایش لیست غذاها باید بتوانید با کلیک بر روی یک خانه از جدول، به صفحه ی افزودن آیتم جدید راه پیدا کنید. پس از هدایت به این scene، با صفحه ی خالی مواجه می شوید که امکان افزودن غذای جدید را فراهم می کند. اما شما می خواهید اطلاعات مربوط به آیتم جاری را ویرایش کنید. در زیر به پیاده سازی این قابلیت خواهید پرداخت.
در زمان حاضر، شما دو segue دارید که هر دوی آن ها کاربر را به scene یکسان (صفحه ی افزودن غذای جدید) هدایت می کنند. اما اگر بخاطر داشته باشید، در این مبحث می خواهید امکان ویرایش اطلاعات آیتم جاری را به کاربر اعطا نمایید. حال این سوال مطرح می شود: از کجا می توان فهمید چه زمان کاربر می خواهد یک غذای جدید به برنامه اضافه کند و چه زمان می خواهد اطلاعات مربوط به غذای جاری را ویرایش کند؟ بنابراین باید روشی تعبیه کنید که به وسیله ی آن بتوانید تشخیص دهید چه زمان کاربر می خواهد غذای جدید اضافه کند و چه زمان مایل به ویرایش یا بروز رسانی اطلاعات مربوط به غذای جاری می باشد.
یادآور می شویم که هرگاه segue اجرا می شود، حتما قبل از آن متد prepareForSegue(_:sender:) فراخوانی می گردد. شما می توانید داخل بدنه ی این متد کدی تعریف کرده و به وسیله ی آن تشخیص دهید کدام segue در حال اجرا است و به تبع آن اطلاعات مربوطه را در meal scene نمایش دهید. اگر به خاطر داشته باشید قبلا برای این segue ها نام مشخصی تعیین کردید. حال با استفاده از نام آن ها، می توانید به راحتی بین segue ها تمایز قائل شده و دقیقا تشخیص دهید کدام segue در حال اجرا است. دو segue به همراه اسم آن ها: 1. AddItem (modal segue) 2. ShowDetail (show segue).
برای تشخیص اینکه کدام segue در حال اجرا است، مراحل زیر را به ترتیب دنبال نمایید:
1. ابتدا فایل MealTableViewController.swift را باز کنید.
2. داخل فایل MealTableViewController.swift، متد prepareForSegue(_:sender:) method را یافته و آن را از حالت comment خارج نمایید. (جهت خارج نمودن متد ذکر شده از حالت comment، کافی است کاراکترهای */ و /* را از طرفین آن حذف نمایید.)
پس از انجام این کار، پیاده سازی که به صورت آماده و به عنوان الگو توسط محیط Xcode در اختیار شما قرار گرفته (template implementation)، به صورت زیر خواهد بود:

   
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
                 

از آنجایی که MealTableViewController یک کلاس مشتق شده از UITableViewController است، پیاده سازی الگو همراه با اسکلت متد prepareForSegue(_:sender:) توسط محیط به صورت آماده در اختیار شما قرار می گیرد.
3. دو خط comment را حذف نموده، سپس دستورات شرطی if و else را جایگزین آن نمایید:

if segue.identifier == "ShowDetail" {
}
else if segue.identifier == "AddItem" {
}

این کد خصیصه ی اسم یا identifier هر یک از دو segue را با اسم تخصیص داده شده به آن ها در کادر Attribute inspector مقایسه می کند.
4. داخل ساختمان اولین دستور شرطی، کد زیر را درج نمایید (این دستور تنها زمانی اجرا می شود که آیتم یا غذای مورد نظر توسط کاربر در حال ویرایش باشد):

let mealDetailViewController = segue.destinationViewController as! MealViewController

این کد با استفاده از عملگر "as!" سعی می کند، view controller مقصد (destination view controller) از segue مورد نظر را به MealViewController که یک کلاس ارث بری شده از آن هست، تبدیل نوع (downcast) نماید. با کمی دقت متوجه می شوید که در انتهای این عملیات بجای "?" از کاراکتر "!" استفاده شده است. معنی استفاده از کاراکتر مزبور در انتهای عملیات جاری این است که کد تلاش می کند به زور عملیات تبدیل را انجام دهد، به طوری که اگر پروسه ی تبدیل با موفقیت صورت پذیرد، مقدار segue.destinationViewController به ثابت محلی mealDetailViewController اختصاص می یابد و در غیر این صورت اپلیکیشن در زمان اجرا به دلیل ناموفق بودن تبدیل به طور ناگهانی از کار می افتد. به عبارت دیگر تبدیل در هر صورت به طور تحمیلی انجام می شود، حتی اگر اصلا امکان آن وجود نداشته باشد که در صورت ناموفق بودن سبب رخداد خطای مهلک در runtime و عدم اجرای برنامه می شود.
با توجه به توضیحات فوق، تنها در صورتی باید از عملگر "as!" استفاده کنید که از امکان پذیر بودن عملیات تبدیل و موفقیت آمیز بودن آن اطمینان کامل دارید. چنانچه مطمئن نیستید که تبدیل به طور حتم با موفقیت انجام می پذیرد، بهتر است از عملگر "as?" استفاده نمایید.
5. در زیر خط قبلی، یک دستور if دیگر به صورت زیر درج نمایید (این دستور در واقع به صورت تودرتو داخل بدنه ی دستور شرطی اول گنجانده می شود):

// Get the cell that generated this segue.
if let selectedMealCell = sender as? MealTableViewCell {
}

این کد سعی می کند با استفاده از علمگر "as?" آبجکت sender را به MealCell تبدیل (downcast) نماید. اگر پروسه ی تبدیل با موفقیت انجام شود، مقدار sender که به MealTableViewCell تبدیل شده، در ثابت محلی selectedMealCell ذخیره می گردد و در پی آن دستور تعریف شده در بدنه ی if اجرا می شود. اما چنانچه تبدیل با شکست مواجه شود، عبارت شرطی در واقع برابر nil بوده و دستور مربوطه به مرحله ی اجرا نمی رسد.
6. داخل ساختمان if، مجموعه دستورات زیر را وارد نمایید:

let indexPath = tableView.indexPathForCell(selectedMealCell)!
let selectedMeal = meals[indexPath.row]
mealDetailViewController.meal = selectedMeal

این کد آبجکت Meal که متناظر یا مربوط به خانه ی انتخاب شده از جدول (table view) می باشد را واکشی می کند. سپس مقدار آبجکت Meal را به متغیر (property) meal از view controller مقصد تخصیص می دهد که نمونه ای از کلاس MealViewController می باشد (destination view controller یا view controller/صفحه ای که segue نهایتا به آن کاربر را هدایت می کند؛ صفحه محتوایی که در انتهای segue مشاهده می شود). شما MealViewController را طوری تنظیم خواهید کرد که به هنگام بارگذاری اطلاعات را از متغیر meal خوانده و نمایش دهد.
7. داخل ساختمان دستور شرطی else، تابع print را با پارامتر ورودی زیر درج نمایید:

print("Adding new meal.")

اگرچه شما در صورت اضافه نمودن آیتم جدید به برنامه اصلا نیازی به این متد ندارید (استفاده از این متد کاملا غیر ضروری می شود)، با این حال بد نیست گزارشی از آنچه در حال رخدادن هست را برای کاربر در UI چاپ نمایید.
بدنه ی متد prepareForSegue( :sender:) هم اکنون می بایست دارای پیاده سازی زیر باشد:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowDetail" {
let mealDetailViewController = segue.destinationViewController as! MealViewController
// Get the cell that generated this segue.
if let selectedMealCell = sender as? MealTableViewCell {
let indexPath = tableView.indexPathForCell(selectedMealCell)!
let selectedMeal = meals[indexPath.row]
mealDetailViewController.meal = selectedMeal
}
}
else if segue.identifier == "AddItem" {
print("Adding new meal.")
}
}

پس از پیاده سازی منطق لازم، می بایست با نوشتن رفتار و کد مناسب در فایل MealViewController.swift، اطمینان حاصل نمایید که UI اپلیکیشن به درستی بروز آوری شده و محتوای مد نظر را برای کاربر به نمایش می گذارد. به عبارتی دقیق تر، زمانی که نمونه یا آبجکتی از کلاس MealViewController (صفحه ی افزودن غذای جدید) ساخته می شود، view های آن (المان های رابط کاربری) بایستی با داده های مناسب از متغیر meal پر شوند (البته در صورت وجود داده ی مورد نظر). اگر بخاطر داشته باشید، مکان مناسب برای انجام این نوع تنظیمات، بدنه ی متد viewDidLoad() است. به منظور بروز رسانی پیاده سازی متد viewDidLoad، مراحل زیر را طی نمایید:
1. فایل MealViewController.swift را باز نمایید.
2. داخل این فایل، متد viewDidLoad() را پیدا کنید.

override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input via delegate callbacks.
nameTextField.delegate = self
// Enable the Save button only if the text field has a valid Meal name.
checkValidMealName()
}

3. در زیر خط nameTextField.delegate، این کد را اضافه نمایید:

// Set up views if editing an existing Meal.
if let meal = meal {
navigationItem.title = meal.name
nameTextField.text = meal.name
photoImageView.image = meal.photo
ratingControl.rating = meal.rating
}

این کد سبب می شود، در صورت non-nil بودن متغیر meal، تمامی آبجکت های view در فایل MealViewController داده های مربوطه را از متغیر meal خوانده و نمایش دهند. این رخداد تنها زمانی اتفاق می افتد که غذا یا آیتم جاری توسط کاربر در حال ویرایش باشد.
در حال حاضر متد viewDidLoad() شما می بایست دارای پیاده سازی زیر باشد:

override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input via delegate callbacks.
nameTextField.delegate = self
// Set up views if editing an existing Meal.
if let meal = meal {
navigationItem.title = meal.name
nameTextField.text = meal.name
photoImageView.image = meal.photo
ratingControl.rating = meal.rating
}
// Enable the Save button only if the text field has a valid Meal name.
checkValidMealName()
}

تست کنید: برنامه ی خود را اجرا نمایید. بایستی بتوانید با کلیک بر روی یکی از خانه های جدول (table view cell)، به صفحه ی افزودن غذای جدید (meal scene) راه پیدا کرده و آن را در حالی که از قبل با داده های مربوط با meal پر شده، مشاهده نمایید. اما هنوز یک جای کار مشکل دارد: با کلیک بر روی دکمه ی Save، بجای اینکه اطلاعات جدید بر روی اطلاعات قبلی غذا نوشته شود، برنامه یک آیتم جدید به لیست غذاها اضافه می کند. در زیر به پیاده سازی رفتار مناسب برای این بخش خواهید پرداخت.

آموزش Edit و Delete درSwift

جهت بازنویسی اطلاعات مربوط به یک غذا در لیست، می بایست اکشن متد unwindToMealList(_:) را طوری ویرایش و بروز رسانی نمایید که بتواند دو سناریو کاملا متفاوت را مدیریت کند. این متد در هر سناریو بایستی بتواند کار متفاوتی انجام دهد: در یکی غذای جدید اضافه کند و در دیگری اطلاعات مربوط به غذای جاری را بازنویسی نماید. یادآور می شویم که این متد تنها زمانی صدا خورده می شود که کاربر بر روی دکمه ی Save کلیک کرده باشد. بنابراین نیازی به اندیشیدن تمهیدات برای دکمه ی Cancel و کد متصل به آن در بدنه ی این متد نیست.
به منظور بروز رسانی پیاده سازی متد unwindToMealList(_:) جهت افزودن غذای جدید یا بازنویسی غذای جاری، مراحل زیر را طی نمایید:
1. فایل MealTableViewController.swift را باز نمایید.
2. داخل این فایل، متد 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)
}
}

3. در ابتدای ساختمان دستور شرطی if، این کد را اضافه نمایید:

if let selectedIndexPath = tableView.indexPathForSelectedRow {
}

این کد بررسی می کند آیا سطری از جدول (table view) انتخاب شده است یا خیر. در صورتی که سطر از جدول انتخاب شده باشد، معنیش این است که کاربر به منظور ویرایش اطلاعات یک آیتم، بر روی سطری از جدول کلیک کرده است. به عبارت روشن تر، دستور نام برده زمانی اجرا می شود که یک آیتم از لیست در حال ویرایش باشد.

4. داخل بدنه ی این دستور شرطی if، کد زیر را درج نمایید:

// Update an existing meal.
meals[selectedIndexPath.row] = meal
tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)

اولین خط از این مجموعه دستور، آیتم مربوطه در meals را جهت بازنویسی و ذخیره ی اطلاعات جدید یا ویرایش شده ی آن، بروز رسانی می کند. دومین خط، سطر مورد نظر را مجددا در جدول بارگذاری نموده و اطلاعات جدید غذا یا آیتم مربوطه را نمایش می دهد.
5. پس از دستور if، یک دستور else اضافه نموده و آن را در چهار خط پایانی متد، به صورت زیر جای دهید:

                    
else {
// Add a new meal.
let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)
meals.append(meal)
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
}

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

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

تست کنید: اپلیکیشن خود را اجرا نمایید. بایستی بتوانید با کلیک بر روی یک سطر از جدول به صفحه ی افزودن غذای جدید (meal scene) راه پیدا کرده و آن را در حالی که از قبل با داده های مرتبط با meal مورد نظر پر شده، مشاهده نمایید. در صورت کلیک بر روی دکمه ی Save، تغییراتی که اخیرا اعمال کردید باید بر روی غذای جاری در لیست بازنویسی شود (جایگزین آن گردد).


آموزش Edit و Delete درSwift

 آموزش Edit و Delete درSwift افزودن قابلیت لغو ویرایش آیتم جاری و بازگشت به صفحه ی لیست غذاها بدون ذخیره ی تغییرات (بروز رسانی کد متصل به دکمه ی Cancel)

کاربر اپلیکیشن شما شاید مایل باشد تغییراتی که به یک meal وارد کرده را لغو و به دنبال آن بدون اینکه تغییرات مزبور را ذخیره کرده باشد، به صفحه ی نمایش لیست غذاها بازگردد. برای این منظور، رفتار دکمه ی Cancel را در کد برنامه طوری ویرایش خواهید کرد که scene مورد نظر را از نمایشگر پنهان نماید. به عبارتی دیگر، آن صفحه را بسته، کاربر را به صفحه ی دیگری هدایت کند.
نحوه ی بستن صفحه و حذف از آن نمایشگر، به نوع ارائه و نمایش آن بستگی دارد. در این بخش شما روشی تعبیه خواهید کرد که طی آن بتوانید تشخیص دهید scene حاضر، چگونه به هنگام کلیک کاربر بر روی دکمه ی Cancel، نمایش داده شده است. اگر به صورت شناور یا modal (در پی کلیک کاربر بر روی دکمه ی Add) بر روی نمایشگر ظاهر شده باشد، متعاقبا به وسیله ی متد dismissViewControllerAnimated(_:completion:) از نمایشگر حذف می شود. حال اگر به سبک push (به واسطه ی یک خانه از جدول یا table view cell) بر روی صفحه به نمایش درآمده باشد، آنگاه توسط همان کلاس navigation controller ای که بر روی نمایشگر پدیدار شد، از صفحه حذف می شود.
به منظور ویرایش و بروز رسانی پیاده سازی متد متصل به دکمه ی Cancel، مراحل زیر را دنبال نمایید:
1. فایل MealViewController.swift را باز نمایید.
2. داخل فایل نام برده، متد cancel(_:) را پیدا کنید.

@IBAction func cancel(sender: UIBarButtonItem) {
dismissViewControllerAnimated(true, completion: nil)
}

این پیاده سازی در حال حاضر تنها از متد dismissViewControllerAnimated برای بستن meal scene (صفحه ی افزودن غذای جدید) بهره می گیرد چرا که تا به اینجا تنها می بایست تمهیدات لازم برای دکمه ی Add را در نظر می گرفتید.
3. داخل ساختمان متد cancel (_:)، قبل از کد جاری، دستور زیر را اضافه نمایید.

// Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
let isPresentingInAddMealMode = presentingViewController is UINavigationController

دستوری که هم اکنون به قطعه کد اضافه کردید، یک مقدار بولی تعریف کرده و طی آن مشخص می کند آیا view controller ای که این صفحه محتوا (scene) را به نمایش می گذارد، از جنس کلاس UINavigationController هست یا خیر. از اسم ثابت isPresentingInAddMealMode پیدا است که meal scene به وسیله ی دکمه ی Add بر روی نمایشگر ارائه می شود. دلیلش این است که meal scene در حالی به این سبک به نمایش در می آید که داخل navigation controller خود جاسازی شده، بدین معنی که این کلاس navigation controller است که صفحه افزودن غذای جدید را در نمایشگر به صورت شناور (modal) ارائه می دهد.
4. حال دستور شرطی زیر را اضافه نموده و خطی که تابع dismissViewControllerAnimated را صدا می زند، در داخل بدنه ی این دستور شرطی جایگذاری نمایید:

if isPresentingInAddMealMode {
dismissViewControllerAnimated(true, completion: nil)
}

اگر بخاطر داشته باشید، قبلا متد dismissViewControllerAnimated همیشه بلافاصله پس از صدا خوردن تابع cancel(_:)، فراخوانده می شد. اما اکنون تنها زمانی اجرا می شود که شرط isPresentingInAddMealMode صادق یا true باشد.
5. بلافاصله پس از دستور شرطی if، عبارت else را به صورت زیر اضافه نمایید:

else {
navigationController!.popViewControllerAnimated(true)
}

در زمان حاضر، این قطعه کد یک دستور if با عبارت شرطی else را در برمی گیرد. دستور موجود در بدنه ی if تنها زمانی اجرا می شود که شرط isPresentingInAddMealMode برقرار یا صحیح باشد و در غیر این صورت دستور داخل ساختمان else اجرا خواهد شد. در حقیقت دستور else زمانی اجرا می شود که meal scene (صفحه ی افزودن غذای جدید) بر روی navigation stack (مجموعه view controller ها) که meal list scene )صفحه ی نمایش لیست غذاها( عضوی از آن است، قرار داده (push) شود. دستور موجود در بدنه ی else یک تابع به نام popViewControllerAnimated را اجرا می کند که view controller جاری (meal scene) را از روی navigation stack کلاس navigationController برداشته (pop off) و همزمان با این کار انتقال یا transition را با انیمیشن به اجرا در می آورد.
هم اکنون پیاده سازی متد cancel(_:) می بایست به صورت زیر باشد:

 @IBAction func cancel(sender: UIBarButtonItem) {
// Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
let isPresentingInAddMealMode = presentingViewController is UINavigationController
if isPresentingInAddMealMode {
dismissViewControllerAnimated(true, completion: nil)
}
else {
navigationController!.popViewControllerAnimated(true)
}
}

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

 آموزش Edit و Delete درSwift پیاده سازی امکان حذف آیتم ها (اضافه کردن دکمه ی Delete)

بد نیست به کاربران اپلیکیشن خود این قابلیت را بدهید تا آیتم دلخواه خود را از لیست حذف کنند. برای این منظور می بایست روشی تعبیه نمایید که طی آن کاربران بتوانند table view (جدول) را در وضعیت ویرایش (editing mode) قرار داده و سپس از آنجا آیتم مد نظرشان را حذف کنند. در این راستا، یک دکمه ی Edit به نوار پیمایش table view اضافه خواهید نمود.
به منظور افزودن دکمه ی Edit به table view، مراحل زیر را دنبال نمایید:
1. فایل MealTableViewController.swift را باز نمایید.
2. داخل فایل ذکر شده، متد viewDidLoad() را پیدا کنید.

override func viewDidLoad() {
super.viewDidLoad()
// Load the sample data.
loadSampleMeals()
}

در زیر خط super.viewDidLoad()، کد زیر را اضافه نمایید:

// Use the edit button item provided by the table view controller.
navigationItem.leftBarButtonItem = editButtonItem()

این کد یک نوع bar button item ایجاد کرده که قابلیت ویرایش را به صورت درون ساخته در خود دارد. سپس این دکمه را به سمت چپ نوار پیمایش در صفحه ی نمایش لیست غذاها (meal list scene) اضافه می کند.,br> متد ViewDidLoad() اکنون بایستی دارای پیاده سازی زیر باشد:

override func viewDidLoad() {
super.viewDidLoad()
// Use the edit button item provided by the table view controller.
navigationItem.leftBarButtonItem = editButtonItem()
// Load the sample data.
loadSampleMeals()
}

تست کنید: برنامه را اجرا نمایید. همان طور که می بینید یک دکمه ی Edit در سمت چپ نوار پیمایش table view قابل مشاهده می باشد. اگر بر روی دکمه ی Edit کلیک نمایید، table view وارد وضعیت ویرایش می شود – اما از آنجایی که هنوز کد لازم برای حذف را پیاده نکرده اید، فعلا نمی توانید سطری را از جدول حذف نمایید.


آموزش Edit و Delete درSwift

جهت انجام هر گونه عملیات ویرایش بر روی table view، شما می بایست یکی از متدهای Delegate آن به نام tableView(_:commitEditingStyle:forRowAtIndexPath:) را پیاده سازی نمایید. این متد وظیفه ی مدیریت سطرهای جدول، زمانی که این سطرها در وضعیت ویرایش قرار دارند (توسط کاربر در حال ویرایش هستند) را بر عهده دارد. علاوه بر آن، لازم است متد tableView(_:canEditRowAtIndexPath:) را از حالت comment خارج نمایید. این متد همان طور که از پارامتر ورودی آن مشخص است، امکان ویرایش را فراهم می کند.
جهت حذف یک meal یا آیتم از لیست، مراحل زیر را دنبال نمایید:
1. در فایل MealTableViewController.swift، متدtableView(_:commitEditingStyle:forRowAtIndexPath:) را یافته و با حذف کاراکترهای */ و /* از طرفین این متد، آن را از حالت comment خارج نمایید. پس وارد کردن این تغییرات، پیاده سازی که به صورت آماده توسط Xcodeدر اختیار شما قرار می گیرد ، به صورت زیر خواهد بود:

// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

در زیر خط توضیح، // Delete the row from the data source، این دستور را اضافه نمایید:

meals.removeAtIndex(indexPath.row)

این کد آبجکت Meal که قرار است از آرایه ی meals پاک شود را حذف می کند. خط پس از آن که بخشی از پیاده سازی ارائه شده توسط Xcodeهست، سطر مربوطه را از table view (جدول) حذف می کند.
2. در فایل MealTableViewController.swift، متد tableView(_:canEditRowAtIndexPath:) را یافته و از حالت comment خارج نمایید. پس از وارد کردن این تغییر، پیاده سازی که به صورت آماده توسط Xcode در اختیار شما قرار می گیرد، به صورت زیر خواهد بود:

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}

در حال حاضر، متد tableView(_:commitEditingStyle:forRowAtIndexPath:) شما می بایست دارای پیاده سازی زیر باشد:

// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
meals.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

تست کنید: برنامه ی خود را اجرا نمایید. با کلیک بر روی دکمه ی Edit، جدول (table view) در وضعیت ویرایش قرار می گیرد. می توانید با کلیک بر روی آیکون قرمز رنگ که در سمت چپ سطر مربوطه قابل مشاهده می باشد، آن سطر را برای حذف انتخاب و آماده نمایید. سپس جهت حذف دائمی آن سطر، دکمه ی قرمز رنگ Delete که در سمت راست سطر مورد نظر به نمایش در آمده را کلیک نمایید.
و یا در صورت تمایل می توانید انگشت خود را بر روی سطر دلخواه در سطح نمایشگر قرار داده آن را به سمت چپ بکشید (swipe)، می بینید که دکمه ی Delete نمایان می شود. این رفتار به صورت درون ساخته و از پیش تعریف شده در آبجکت table view وجود دارد. پس از کلیک بر روی دکمه ی Delete، سطر متناظر به طور دائمی از جدول حذف می شود.

  • 1326
  •    1228
  • تاریخ ارسال :   1395/08/06

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

ارسال

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

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