متصل کردن UI (ظاهر یا رابط کاربری برنامه) به کد (رفتارها و عملیاتی که برنامه انجام می دهد)
در این مبحث، شما UI ساده ی اپلیکیشن FoodTracker (یا ثبت و رصد اطلاعات غذا) را به کد برنامه متصل می نمایید. با استفاده از این کد امکان انجام عملیات خاصی بر روی UI را برای کاربر برنامه ی خود فراهم می کنید.
در پایان برنامه ظاهری مشابه زیر خواهد داشت:
![clip_image002[6] clip_image002[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image002%5B6%5D_thumb_18.png)
آنچه خواهید آموخت
· رابطه ی بین یک scene در storyboard و view controller زیرین آن را درک کرده و توضیح دهید.
· با استفاده از outlet و action بین المان های UI در سطح storyboard و کد برنامه (source code) ارتباط برقرار کنید.
· ورودی کاربر از یک کادر متن یا text field را خوانده، پردازش کنید و سپس خروجی آن را در UI اپلیکیشن به نمایش بگذارید.
· یک کلاس را بر اساس protocol خاص پیاده سازی کنید (property ها و متدهای تعیین شده توسط آن protocol را در کلاس پیاده سازی کنید).
· با الگوی توسعه ی delegation آشنا شوید.
· در طراحی معماری اپلیکیشن از الگوی توسعه ی target-action پیروی نمایید (الگوی توسعه ی target-action را در معماری اپلیکیشن پیاده سازی کنید).
متصل کردن UI به کد برنامه (Source Code)
المان هایی که در storyboard مشاهده می کنید، در واقع هر یک به بخشی از source code وصل است. شما باید این رابطه ی بین storyboard با کد برنامه را به خوبی درک کنید.
در Storyboard، یک scene نشانگر صفحه ای از صفحات متعدد برنامه است که بخشی از محتوای برنامه و عموما یک view controller را شامل می شود. view controller ها رفتار (متدهای) اپلیکیشن شما را پیاده سازی می کنند.
view controller تنها یکview content و view های زیرمجموعه ی آن را اداره می کند (content view = view دربرگیرنده ی تمامی view ها یا آبجکت های یک scene همچون button، text field و label).
View controller ها: 1. تعاملات/گردش اطلاعات بین data model برنامه (بخشی که داده های اپلیکیشن را کپسوله سازی می کند) و view ها را (بخش هایی که داده های برنامه را برای کاربر به نمایش می گذارد) مدیریت می کند 2. چرخه ی حیات content view های برنامه (view ای که در بالای سلسله مراتب قرار گرفته و نقش ظرف را برای view های فرزند خود همچون button، label ایفا می کند) را از ابتدا تا انتها مدیریت می نماید 3. تغییرات در جهت نمایش برنامه را به هنگام چرخش دستگاه اداره می کند 4. قابلیت پیمایش در برنامه را تعریف کرده 5. و در پایان رفتاری که به ورودی کاربر واکنش نشان می دهد را پیاده سازی می نماید.
تمامی آّبجکت های view controller در IOS، از جنس کلاس UIViewController یا یکی از کلاس های فرزند آن هستند.
رفتار view controller ها را بایستی در کد با ایجاد و پیاده سازی subclass های اختصاصی از view controller (کلاس های فرزند view controller با پیاده سازی اختصاصی خود)، تعریف نمایید. سپس می توانید یک اتصال بین کلاس های مذکور و scene ها در storyboard ایجاد کرده و در نهایت برنامه ای داشته باشید که رفتار تعریف شده در کد (کلاس های view controller) را همراه با UI مورد نظر در storyboard، ارائه می دهد.
Xcode قبلا چنین کلاسی را با نام ViewController.swift ایجاد کرده و آن را به scene جاری که هم اکنون در storyboard با آن کار می کنید، متصل کرده است. در آینده، همین که scene های بیشتری را به برنامه اضافه می کنید، این اتصال بین scene و view controller را خود از طریق Identity inspector برقرار می نمایید.
Identity inspector این امکان را به شما می دهد تا آن دسته از property های یک آبجکت را که با identity آن مرتبط هستند، مانند اینکه به کدام کلاس تعلق دارد، ویرایش نمایید.
![clip_image004[6] clip_image004[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image004%5B6%5D_thumb_13.png)
در زمان اجرای برنامه (runtime)، storyboard نمونه ای از کلاس ViewController می سازد (همان subclass اختصاصی view controller). صفحه ای از برنامه را که در storyboard می بینید، رابط کاربری و ظاهر خود را از scene جاری گرفته، و رفتارهایش، عملیاتی که می تواند انجام دهد، را از کدهای فایل ViewController.swift دریافت می کند.
اگرچه scene مورد نظر به کدهای فایل ViewController.swift متصل است، اما این اتصال به تنهایی برای داشتن تعامل بین بخش های مختلف برنامه کافی نیست. برای تعریف تعامل در برنامه ی خود، کد view controller بایستی بتواند با view های موجود در storyboard (آبجکت های text field، label) تبادل اطلاعات داشته باشد. این کار را با ایجاد connection های بیشتر – که outlet و action خوانده می شوند – بین view ها در storyboard و فایل های view controller انجام می دهید.
تعریف Outlet برای المان های UI
Outlet روشی تعریف می کند که می توان به وسیله ی آن به آبجکت های رابط کاربری – آبجکت هایی نظیر label، button که به storyboard اضافه شده – از کد فایل های source code اشاره کرد (دسترسی داشت).
برای ایجاد outlet، کافی است از آبجکت مورد نظر در storyboard، به فایلview controller ، control-drag کنید. بدین معنی که با کلیک بر روی آن آبجکت، نگه داشتن کلید control و کشیدن آن به فایل view controller، یک اشاره گر از آن آبجکت در فایل view controller ایجاد نمایید.
این عملیات یک (متغیر) property برای آبجکت مورد نظر در فایل view controller ایجاد می کند و به شما اجازه می دهد در زمان اجرا از کد به آن آبجکت دسترسی داشته و آن را دستکاری کنید.
با توجه به آنچه گفته شد، جهت دسترسی یا اشاره به label و text field در لایه ی رابط کاربری، باید برای آن ها در کد outlet تعریف نمایید.
به منظور وصل کردن المان text field به کد فایل ViewController.swift:
1. فایل Main.storyboard را باز کنید.
2. Assistant editor را با کلیک بر روی دکمه ی Assistant، واقع در نوار ابزار Xcode، بالای محیط گوشه ی سمت راست، باز نمایید.
![clip_image006[6] clip_image006[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image006%5B6%5D_thumb_12.png)
3. اگر به فضای کاری بیشتری نیاز دارید، می توانید project navigator و utility area را با کلیک بر روی دکمه های مربوطه در نوار ابزار Xcode پنهان نمایید (جمع کنید).
![clip_image008[6] clip_image008[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image008%5B6%5D_thumb_8.png)
در صورت لزوم می توانید outline view را نیز جمع کنید.
4. در editor selector bar، در بالای assistant editor، این مسیر را طی کنید: Preview -> Automatic -> viewController.swift.
![clip_image010[6] clip_image010[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image010%5B6%5D_thumb_6.png)
محتویات فایل ViewController.swift در ویرایشگر سمت راست محیط به نمایش در می آید.
1. در فایل ViewController.swift، خطی که کلیدواژه ی class را دارد، پیدا کنید:
class ViewController: UIViewController {
2. در زیر کد ذکر شده، عبارت ذیل را درج کنید:
// MARK: Properties
با این کار در واقع یک comment (کد درج توضیحات) به source code خود اضافه می کنید. همان طور که قبلا گفته شد، comment یک تکه متن در فایل source code است که به هنگام کامپایل به عنوان بخشی از دستورات برنامه ترجمه و اجرا نمی شود، اما اطلاعات کاربردی در خصوص بخش های مختلف کد ارائه می دهد.
Comment ای که با کاراکترهای // MARK: آغاز می شود، یک نوع خاص comment است که بیشتر به منظور سازمان دهی کد و کمک در فهم کاربرد آن بخش مورد استفاده قرار می گیرد.
به عنوان نمونه، تکه کدی که شما به عنوان comment به فایل نام برده اضافه کردید، اعلان می کند که در آن بخش property های آبجکت لیست می شوند.
1. در storyboard، المان text field را انتخاب کنید.
2. بر روی المان مذکور در canvas کلیک کرده، کلید control را نگه دارید، سپس آن را کشیده و در زیر بخش comment در assistant editor جایگذاری نمایید.
![clip_image012[6] clip_image012[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image012%5B6%5D_thumb_5.png)
3. یک پنجره ی محاوره ای به نمایش در می آید. در فیلد Name، واژه ی nameTextField را وارد کنید.
لازم نیست دیگر تنظیمات را تغییر دهید.
![clip_image014[6] clip_image014[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image014%5B6%5D_thumb_5.png)
4. حال بر روی دکمه ی Connect کلیک نمایید. Xcode کد لازم را به فایل ViewController.swift، جهت ذخیره ی اشاره گری (pointer) به text field اضافه کرده و storyboard را برای برقراری اتصال مورد نیاز بین المان UI و کد تنظیم می کند. به عبارت واضح تر، Xcode یک اشاره گر (در قالب متغیر یا property) به المان UI مورد نظر، در فایل ViewController.swift اضافه کرده و سپس storyboard را جهت برقراری ارتباط بین المان مورد نظر در لایه ی رابط کاربری با کد مربوطه ی آن در فایل مزبور تنظیم می کند.
@IBOutlet weak var nameTextField: UITextField!
مدت زمانی را به فهم این خط کد اختصاص دهید.
خصیصه (attribute) IBOutlet این امکان را برای شما فراهم می کند تا در محیط Xcode از interface builder به متغیر (property) nameTextField وصل شوید (پیشوند IB نیز به همین امکان اشاره دارد). کلیدواژه ی weak بیانگر قابلیت nil بودن متغیر در طول عمر آن می باشد (بدین معنی که property مذکور می تواند در برهه ای از زمان هیچ مقداری نداشته باشد). در بقیه ی (تعریف) کد صرفا یک متغیر از نوع (کلاس) UITextField، به نام nameTextField ایجاد می شود.
به علامت تعجب "!" در انتهای تعریف outlet دقت کنید. اگر بخاطر داشته باشید، برخی از property ها در فایل AppDelegate.swift این علامت را در انتهای خود دارند. علامت مزبور نشانگر این است که متغیر یا property مورد نظر از نوع implicitly unwrapped optional است. implicitly unwrapped optional، یک متغیر از جنس optional است که پس از مقداردهی اولیه همیشه حاوی مقدار خواهد بود (optional متغیری که می تواند مقداری داشته/نداشته باشد).
حال label را مانند المان قبلی (text field) به کد مربوطه ی آن در فایل ViewController.swift متصل کنید.
برای وصل کردن المان label به کد مربوطه در فایل ViewController.swift:
1. Label را در storyboard انتخاب نمایید.
2. بر روی المان مذکور در canvas کلیک کرده و کلید Control را نگه دارید، سپس آن را کشیده و در assistant editor، زیر متغیر nameTextField جایگذاری کنید.
![clip_image016[6] clip_image016[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image016%5B6%5D_thumb_5.png)
3. در کادر محاوره ای که نمایان می شود، در فیلد Name، واژه ی mealNameLabel را به عنوان اسم المان وارد نمایید. لازم نیست تنظیمات دیگری انجام دهید.
![clip_image018[6] clip_image018[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image018%5B6%5D_thumb_2.png)
4. بر روی Connect کلیک نمایید.
Xcode یک اشاره گر (pointer) در قالب متغیر به المان Label در فایل ViewController.swift اضافه کرده، سپس storyboard را جهت برقراری ارتباط بین المان UI مورد نظر و کد مربوطه ی آن در فایل مذکور، تنظیم می کند. این outlet به استثنای دو ویژگی نوع و اسم، کاملا مشابه المان قبلی است (outlet جاری از نوع کلاس UILabel است که با نوع آبجکت در storyboard کاملا همخوانی دارد).
1. @IBOutlet weak var mealNameLabel: UILabel!
حالا که روشی برای اشاره و دسترسی به المان های UI از داخل کد (در فایل ViewController.swift) دارید، باید یک رخداد که توسط کاربر فعال می شود و زمینه ی تعامل میان این دو المان را فراهم می کند، تعریف نمایید. برای تعریف این رخداد در IOS از action بهره می گیریم.
تعریف یک رخداد با استفاده از Action
اپلیکیشن های IOS رخداد محور هستند (بر اساس الگوی برنامه نویسی رخداد محور/event-driven طراحی می شوند). بدین معنی که روند اجرای (flow) برنامه توسط event ها: رخدادهای سیستم و action های کاربر (کلیک موس یا فشردن کلیدهای کیبورد یا دکمه ای بر روی صفحه) تعیین می گردد.
کاربر با UI برنامه تعامل برقرار کرده ، برای مثال یک دکمه را کلیک می کند، در پی این عمل/action کاربر رخداد خاصی اتفاق می افتد. این رخدادها خود سبب اجرای منطق برنامه و تغییر در داده های آن می شود. سپس واکنش برنامه به عمل کاربر و اثر آن، در UI برنامه منعکس می شود.
همان طور که می دانید در برنامه های رویداد محور، کنترل اجرای بخش هایی از برنامه به دست کاربر است. بدین معنی که زمانی که کاربر با UI برنامه تعامل می کند، بخش های مختلف از کد برنامه در پاسخ به عمل کاربر اجرا می شود. حال از آنجایی که کاربر، نه شما، کنترل اینکه چه زمانی بخش هایی از کد برنامه اجرا شوند را در دست دارد، شما به عنوان برنامه نویس بایستی مشخص کنید کاربر دقیقا اجازه ی انجام چه عملیاتی را دارد و در پاسخ به آن اعمال دقیقا چه واکنشی بایستی نشان داده شود (چه اتفاقی رخ دهد).
Action (یا action method) یک تکه کد است که به event یا رخدادی در برنامه وصل بوده و با اتفاق افتادن آن event فراخوانی و اجرا می شود. به عبارتی دیگر زمانی که آن event رخ می دهد، متعاقبا کد یا دستور مرتبط با آن اجرا می گردد.
می توانید با تعریف action، عملیات دلخواه را پیاده سازی کنید. حال این عملیات می تواند دستکاری داده های مشخص، بروز رسانی بخشی از UI و یا هر عملیات دیگری باشد. در واقع شما با استفاده از action جریان یا روند اجرای برنامه را در پاسخ به رخدادهای فعال شده توسط کاربر و سیستم تعیین می کنید.
تعریف action و outlet به یک نحو صورت می گیرد: کافی است بر روی آبجکت مورد نظر کلیک کرده، کلید control را نگه دارید. سپس آن را کشیده و داخل فایل view controller جایگذاری نمایید. به دنبال آن یک متد در فایل view controller تعریف می شود که به مجرد تعامل کاربر با آبجکت متصل (به آن متد)، فراخوانده و اجرا می گردد.
کار را با ایجاد یک action ساده آغاز نمایید: زمانی که کاربر در UI برنامه، دکمه ی Set Default Label Text را فشار می دهد، شما باید label را طوری تنظیم کرده باشید که (به مجرد فشرده شدن دکمه) مقدار پیش فرض Default Text را نمایش دهد. (در بخش بعدی label را طوری تنظیم می کنیم که مقدار وارد شده در text field را عینا نمایش دهد.)
جهت ایجاد یک action برای بازگردانی مقدار label به Default Text در فایل ViewController.swift، مراحل زیر را گام به گام دنبال نمایید:
1. در فایل ViewController.swift، به قبل از آخرین "}"، عبارت زیر را اضافه نمایید:
// MARK: Actions
comment فوق نشانگر این است که action های کد در این بخش قرار می گیرند.
2. بر روی دکمه ی Set Default Label Text کلیک کرده، کلید control را نگه دارید. سپس المان مزبور را کشیده و داخل فایل ViewController.swift، در زیر comment درج شده (// MARK: Actions)، جایگذاری کنید.
![clip_image020[6] clip_image020[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image020%5B6%5D_thumb_4.png)
3. در کادر محاوره ای که پدیدار می شود، در فیلد Connection گزینه ی Action را انتخاب نمایید.
4. در فیلد Type، گزینه ی UIButton را انتخاب نمایید.
حتما متوجه شدید که مقدار فیلد Type به صورت پیش فرض بر روی AnyObject تنظیم می شود. در زبان Swift، AnyObject یک نوع است و برای توصیف آبجکتی که می تواند به هر کلاسی تعلق داشته باشد، بکار می رود. تنظیم نوع این action method بر روی مقدار UIButton، بیانگر این است که تنها آبجکت های از جنس کلاس UIButton می توانند به این متد یا action وصل شوند. کادر محاوره ای پس از وارد کردن مقادیر مورد نیاز در آن به صورت زیر خواهد بود:
![clip_image022[6] clip_image022[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image022%5B6%5D_thumb_1.png)
5. اکنون بر روی دکمه ی Connect کلیک نمایید.
محیط Xcode خود تعریف و کد لازم برای action method را اضافه می کند.
@IBAction func setDefaultLabelText(sender: UIButton) {
}
در این کد، پارامتر sender به آبجکتی که action را صدا زده و اجرای آن را سبب می شود – در این سناریو همان آبجکت button – اشاره دارد. خصیصه (attribute) IBAction نشانگر این است که متد مورد نظر یک action بوده که می توان از storyboard در interface builder به آن وصل شد. بقیه ی کد صرفا یک متد متعارف به نام setDefaultLabelText(_:) را تعریف می کند.
در حال حاضر، تعریف متد هیچ پیاده سازی در بدنه ی خود ندارد. در زیر کدی به بدنه ی متد اضافه می کنیم که مقدار label را به یک مقدار پیش فرض برمی گرداند.
به منظور پیاده سازی action یا متدی که مقدار label را در فایل ViewController به Default Text برمی گرداند، مراحل زیر را طی نمایید:
1. در فایل ViewController.swift، تعریف متد setDefaultLabelText را پیدا کنید.
2. داخل بدنه ی متد (بین {})، این خط کد را اضافه نمایید:
mealNameLabel.text = "Default Text"
همان طور که حدس می زنید، این کد مقدار text (که یکی از property های label است) را برابر Default Text قرار می دهد. اگر به کد دقت کنید، متوجه می شوید که نوع Default Text را صریحا مشخص نکردیم و نیازی هم به این کار نیست. چراکه زبان Swift قابلیتی به نام type inference (استنتاج نوع) دارد و با استفاده از آن می تواند درست حدس بزند که مقداری از نوع رشته را به آبجکتی از جنس کلاس NSString تخصیص می دهید.
هم اکنون کد action method شما باید به صورت زیر باشد:
@IBAction func setDefaultLabelText(sender: UIButton) {
mealNameLabel.text = "Default Text"
}
تست کنید: تغییراتی که تاکنون به کد اعمال کرده اید را با شبیه ساز (Simulator) تست نمایید. زمانی که بر روی دکمه ی Set Default Label Text کلیک می کنید، مقدار label بایستی از Meal Name (مقداری که در storyboard تنظیم کردید) به Default Text (مقداری که در بدنه ی متد یا action تعریف کردید) تغییر کند.
![clip_image024[6] clip_image024[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image024%5B6%5D_thumb.png)
رفتاری که با این مثال پیاده سازی کردید، مصداق و نمونه ای از پیاده سازی الگوی توسعه ی target-action در طراحی برنامه های IOS است. target-action یک الگوی توسعه یا design pattern است که در آن آبجکت مورد نظر، با اتفاق افتادن یا فعال شدن رخدادی معین، message یا پیغامی را به آبجکت دیگری ارسال می کند. در این سناریو، event کلیک کاربر بر روی دکمه ی Set Default Label Text است، action همان متد setDefaultLabelText است، target همان ViewController، جایی که متد در آن تعریف شده است و در پایان sender (ارسال کننده ی پیغام) دکمه ی Set Default Label Text است.
Message در واقع یک action method است که در source code تعریف شده و target –دریافت کننده ی پیغام – آن آبجکتی است که قادر به اجرای action یا عملیات تعریف شده توسط متد می باشد. آبجکتی که پیغام را ارسال می کند معمولا یک کنترل همچون button، slider یا switch است که در پاسخ به عمل کاربر (لمس صفحه ی نمایش، کشیدن یا تغییر مقدار) رخدادی را فعال می کند (به ورودی کاربر واکنش نشان داده و رخدادی را اجرا می کند).
همان طور که گفته شد این الگو به وفور در برنامه نویسی IOS پیاده سازی شده و شما نمونه های بیشتری از آن را در مباحث بعدی این سری آموزشی مشاهده خواهید کرد.
پردازش ورودی کاربر (برابر قرار دادن مقدار label با مقدار وارد شده توسط کاربر در text field)
در حال حاضر، برنامه طوری تنظیم است که با کلیک بر روی دکمه، مقدار label را بر روی Default Text قرار می دهد. اکنون می خواهیم رفتاری برای برنامه تعریف کنیم که با کلیک بر روی دکمه ی آن، مقدار label را برابر مقدار وارد شده توسط کاربر در text field قرار دهد.
در این بخش جهت ساده نگه داشتن برنامه، برای اعلان زمان بروز رسانی مقدار label، متکی به action کاربر که همان کلیک بر روی دکمه ی Return صفحه کلید است، خواهید بود.
برای پردازش و کار با ورودی کاربر از آبجکت text field، به یک delegate از آبجکت مزبور نیاز دارید. Delegate یک آبجکت است که به نمایندگی از یا با همکاری آبجکت دیگری کاری را انجام می دهد. آبجکتی که کاری را به آبجکت دیگر محول می کند (به آن اشاره می کند) یا با هماهنگی آن آبجکت کاری را انجام می دهد در اینجا delegating object نامیده می شود. آن آبجکتی که کاری از جانب delegating object به آن سپرده می شود، delegate خوانده می شود.
Delegating object (در این مثالtext field )، یک اشاره گر (reference) از آبجکت دیگر (delegate) نزد خود نگه داشته و در زمان مناسب، delegating object نام برده یک پیغام به delegate ارسال می کند. حال این پیغام به delegate درباره ی رخدادی خبر می دهد که delegating object در صدد مدیریت آن بوده و یا به تازگی مدیریت کرده است. در پی آن، delegate با بروز رسانی ظاهر/وضعیت خود، آبجکت دیگر در برنامه یا بازگردانی مقداری که تعیین می کند یک رخداد در حال وقوع چگونه اداره شود، به این دست رخدادها واکنش نشان می دهد.
delegate این text field، زمانی که مقدار کنترل مورد نظر (text field) در حال ویرایش است، با آن تعامل داشته و کاملا اطلاع دارد چه زمانی رخدادهای مهم اتفاق می افتد – مانند اینکه کاربر چه زمانی ویرایش متن را آغاز و کی آن را متوقف می کند. delegate می تواند با استفاده از این اطلاعات، داده ها را در زمان مناسب ذخیره/حذف کند، صفحه کلید را ببندد و غیره ... .
هر آبجکتی می تواند به عنوان delegate آبجکتی دیگری ایفای نقش کند مادام اینکه از الگو یا protocol مناسب پیروی نماید. Protocol یا الگویی که delegate کنترل field text را تعریف می کند، UITextFieldDelegate نام دارد (protocol = صرفا یک الگو و معرفی یک سری متد و property است. اگر برای آبجکت یا کلاسی protocol اعلان کنید، آن کلاس یا آبجکت ملزم به پیاده سازی متدها و property های تعیین شده توسط آن protocol می شود). در این مثال، از آنجایی که ViewController اشاره گر به آبجکت text field را نگهداری می کند، view controller را delegate آن text field انتخاب می کنیم.
ابتدا بایستی ViewController را بر اساس protocol یا الگوی UITextFieldDelegate تنظیم و پیاده سازی کنید. برای استفاده از protocol خاص، کافی است آن را در خط تعریف کلاس لحاظ نمایید.
به منظور پیروی از الگوی پیاده سازی UITextFieldDelegate در view controller و انتساب کلاس نام برده به عنوان دلیگیت text field، مراحل زیر را گام به گام دنبال نمایید:
1. در صورتی که assistant editor باز است، با کلیک بر روی آخرین دکمه، از سمت چپ، standard editor را باز کنید.
![clip_image026[6] clip_image026[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image026%5B6%5D_thumb_1.png)
Project navigator و utility area را با کلیک به ترتیب بر روی دکمه های Navigator و Utilities در نوار ابزار محیط Xcode (اشاره شده در تصویر فوق) باز نمایید.
2. در project navigator، بر روی فایل ViewController.swift کلیک کرده و آن را باز نمایید.
3. داخل فایل مزبور، خط حاوی کلیدواژه ی class را پیدا کنید:
class ViewController: UIViewController {
4. پس از UIViewController، یک ویرگول اضافه نموده و سپس UITextFieldDelegate را درج نمایید. با این کار شما protocol نام برده را adopt می کنید یا به عبارتی الگویی برای معرفی آن کلاس به عنوان delegate ارائه می دهید (protocol = صرفا یک الگو و معرفی یک سری متد و property است. اگر برای آبجکت یا کلاسی protocol اعلان کنید، آن کلاس یا آبجکت ملزم به پیاده سازی متدها و property های تعیین شده توسط protocol می شود).
class ViewController: UIViewController, UITextFieldDelegate {
با اضافه نمودن این protocol به خط تعریف کلاس ViewController، به کلاس ذکر شده این قابلیت را دادید که خود را به عنوان UITextFieldDelegate معرفی کند. به عبارت دیگر شما می توانید از این پس، از کلاس نام برده به مثابه ی delegate آبجکت text field استفاده کرده، برخی از رفتارهای (متدهای) آن را پیاده سازی و بدین وسیله ورودی کاربر را مدیریت نمایید.
به منظور انتساب کلاس ViewController به عنوان delegate آبجکت nameTextField، مراحل زیر را دنبال نمایید:
1. داخل فایل ViewController.swift ،متد viewDidLoad() را پیدا کنید:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
در پیاده سازی این متد یک comment مشاهده می کنید. نیازی به این comment نیست، می توانید آن را حذف کنید.
2. در زیر دستور super.viewDidLoad()، ابتدا یک خط خالی ایجاد کرده، سپس کد زیر را وارد نمایید:
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
کلیدواژه ی self به کلاس ViewController اشاره دارد، زیرا آبجکت text field در محدوده یا scope تعریف کلاس ViewController مورد اشاره قرار گرفته است.
شما می توانید برای فهم کاربرد و استفاده ی هر بخش کد، توضیحات و comment در زیر آن درج نمایید.
پس از اعمال تغییرات فوق، کد شما باید مشابه زیر باشد:
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
در این بخش از کد ورودی کاربر در تکست فیلد را از طریق توابع بازفراخوان یا کالبک دلیگیت مدیریت می کنیم//
nameTextField.delegate = self
}
اکنون کلاس ViewController یک delegate برای آبجکت nameTextField است.
UITextFieldDelegate تعدادی متد اختیاری نیز ارائه می دهد که شما ملزوم به پیاده سازی آن ها نیستید. اما برای اینکه برنامه جاری رفتار و عملیات دلخواه را داشته باشد، بایستی دو متد از مجموع متدهای آن را پیاده سازی کنید:
func textFieldShouldReturn(textField: UITextField) -> Bool
func textFieldDidEndEditing(textField: UITextField)
برای درک اینکه چه زمان این متدها فراخوانده شده و چه کارهایی را انجام می دهند، آگاهی از نحوه ی عملکرد و واکنش text field ها به ورودی کاربر لازم و ضروری است.
زمانی که کاربر text field را با قابلیت لمس انتخاب می کند، کنترل نام برده (text field) به صورت خودکار first responder می شود. در یک برنامه، first responder اولین آبجکتی است که انواع event های برنامه از جمله key event ها (رخدادهای مربوط به دکمه)، motion event (رخدادهای مربوط به حرکت یا تکان خوردن دستگاه)، action message ها و غیره ... را دریافت می کند. به عبارت دیگر، بسیاری از رخدادهای فعال شده بر اثر اَعمال کاربر ابتدا به first responder ارجاع داده می شوند.
از آنجایی که text field به صورت پیش فرض اولین المان واکنش دهنده یا first responder می باشد، سیستم عامل IOS صفحه کلید را به نمایش گذاشته و session ویژه ی درج و ویرایش مقدار آن المان را مهیا و راه اندازی می کند. آنچه کاربر با فشردن دکمه های صفحه کلید تایپ می کند، بلادرنگ وارد المان text field می شود.
زمانی که کاربر قصد دارد ویرایش مقدار text field را متوقف کند، text field بایستی از موقعیت خود به عنوان first responder دست بکشد (از این وضعیت خارج شود). به دنبال این اتفاق، چون که المان text field دیگر آبجکت فعال در برنامه نیست، رخدادهای بعدی می بایست به آبجکت دیگری ارجاع یا سوق داده شوند.
در اینجا است که پیاده سازی متدهای UITextFieldDelegate بکار گرفته و اجرا می شود. شما می بایست اعلان کنید که با اتمام editing session و کلیک کاربر بر روی دکمه ی مربوطه (Return یا Done)، المان text field بایستی از موقعیت خود به عنوان first responder دست بکشد (جایگاه خود به عنوان آبجکت فعال در پنجره و دریافت کننده ی تمامی رخدادها رها کند). این کار را در بدنه ی متد textFieldShouldReturn(_:) تعریف و پیاده سازی می کنید. متد مذکور زمانی که کاربر بر روی دکمه ی Return (یا در مثال جاری دکمه ی Done) کلیک می کند، فراخوانده و متعاقبا اجرا می گردد.
جهت پیاده سازی متد textFieldShouldReturn(_:) از protocol یا الگوی UITextFieldDelegate، مراحل زیر را دنبال نمایید:
1. داخل فایل ViewController.swift، در بالای بخش // MARK: Actions، کد زیر را وارد نمایید:
// MARK: UITextFieldDelegate
این comment یا کد درج توضیحات به سازمان دهی کد، خوانایی بیشتر و فهم کاربرد بخش های مختلف آن کمک شایانی می کند.
تاکنون تعداد زیادی از این comment ها را به کد خود اضافه کردید. Xcode هر یک از این comment ها را به صورت یک section title (متن یا عنوان توصیف کننده ی بخشی از سند یا صفحه) در functions menu فایل کد اصلی برنامه (source code) لیست می کند. برای دسترسی به functions menu، کافی است بر روی اسم فایل مربوطه در بالای ناحیه ی ویرایش (editor area) کلیک نمایید. functions menu به شما امکان می دهد تا با کلیک بر روی آیتم های قابل گزینش آن، به بخش های مرتبط در کد خود پیمایش کنید (بپرید). با کمی دقت می بینید که کلیه ی بخش هایی که قبلا با // MARK: علامت گذاری کردید، در این بخش قابل مشاهده می باشد. می توانید بر روی یکی از section title ها کلیک کرده تا به سرعت به بخش مربوطه در فایل هدایت شوید.
2.
در زیر comment، متد زیر را درج نمایید:
func textFieldShouldReturn(textField: UITextField) -> Bool {
}
3. در بدنه ی این متد، کد زیر را وارد نموده تا text field از موقعیت خود به عنوان first responder دست بکشد. همچنین یک comment جهت ارائه ی توضیحات در خصوص کاربرد کد، در بالای آن درج نمایید.
// Hide the keyboard.
textField.resignFirstResponder()
4. سعی کنید خط دوم کد را (متد textField.resignFirstResponder()) را (بجای کپی و پیست) به صورت دستی تایپ کنید. در حین کدنویسی متوجه خواهید شد که Xcode سعی می کند بر اساس شرایط و بستر جاری، کدی که قصد وارد کردن آن را دارید، حدس زده و بخش های بعدی آن را به شما پیشنهاد کند. این ویژگی که code completion نامیده می شود، تنها یکی از امکانات Xcode است که در افزایش سرعت برنامه نویسی می تواند کمک شایانی به شما بکند. زمانی که Xcode لیست پیشنهادات یا کدهای تکمیل کننده ی خود را به صورت لیست ارائه می دهد، کافی است با نوار پیمایش آن به پایین لیست رفته و پس از یافتن مورد مناسب، کلید Return را فشار دهید. خواهید دید که Xcode کل خط را به صورت خودکار برای شما وارد می کند.
![clip_image030[6] clip_image030[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image030%5B6%5D_thumb.png)
5. در بدنه ی متد جاری، دستور زیر را نیز وارد نمایید:
1. return true
از آنجایی که این متد یک مقدار بولی (Boolean) در خروجی برمی گرداند، بازگردانی مقدار true توسط متد مورد نظر نشانگر این است که text field بایستی در پاسخ به اِعمال کلید Return (توسط کاربر) صفحه کلید را ببندد (از موقعیت خود به عنوان first-responder یا آبجکت فعال در پنجره دست بکشد).
متد textFieldShouldReturn(_:) هم اکنون می بایست مشابه زیر باشد:
func textFieldShouldReturn(textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
دومین متدی که باید پیاده سازی کنید، textFieldDidEndEditing(_:)، زمانی فراخوانده می شود که text field از موقعیت خود به عنوان اولین آبجکت واکنش دهنده (first-responder) دست بکشد (از این وضعیت خارج شود). این متد پس از اجرای textFieldShouldReturn (متدی که در بالا پیاده سازی کردید)، صدا خورده می شود.
تابع textFieldShouldReturn به شما این امکان را می دهد تا اطلاعات وارد شده در text field را خوانده و آن را برای منظور خاصی بکار ببرید. برای مثال، در شرایط فعلی شما مقدار وارد شده در text field را گرفته و از آن برای تغییر مقدار label در رابط کاربری برنامه ی خود استفاده می کنید.
جهت پیاده سازی متد textFieldDidEndEditing(_:) از protocol یا الگوی UITextFieldDelegate، کافی است مراحل زیر را گام به گام دنبال نمایید:
1. داخل فایل ViewController.swift، پس از متد textFieldShouldReturn(_:)، متد زیر را درج نمایید:
func textFieldDidEndEditing(textField: UITextField) {
}
2. در بدنه ی این متد، دستور زیر را وارد نمایید:
1. mealNameLabel.text = textField.text
با افزودن این متد خواهید توانست مقدار وارد شده در text field را جایگزین مقدار label (در بالای کادر متن) کرده و این تغییر را در UI معنکس و برای کاربر نمایش دهید.
در حال حاضر کد متد textFieldDidEndEditing(_:) شما باید به صورت زیر باشد:
func textFieldDidEndEditing(textField: UITextField) {
mealNameLabel.text = textField.text
}
تست کنید: برنامه ی خود را به همراه تمامی تغییراتی که اعمال کرده اید، در محیط شبیه ساز/ Simulator اجرا و تست کنید. در برنامه باید بتوانید text field را انتخاب کرده و مقداری از نوع متن را در آن وارد کنید. زمانی که بر روی دکمه ی Done کلیک می کنید، صفحه کلید باید بسته شده و متن label می بایست مقدار وارد شده در text field را عینا نمایش دهد. حال اگر بر روی دکمه ی Set Default Label Text کلیک نمایید، مقدار label بایستی تغییر کرده و به مقدار اولیه Default Text (مقداری که قبلا توسط action تعیین کرده بودید) بازگردد .
![clip_image031[6] clip_image031[6]](http://articles.tahlildadeh.com/image.axd?picture=clip_image031%5B6%5D_thumb_1.png)