در این مقاله قصد داریم به بررسی یک برنامه حل سودوکو و الگوریتمهای مورد استفاده از سوی آن بپردازیم. سپس این راهحلها را در جاوا پیادهسازی میکنیم. نخستین راهحل یک حمله «تهاجم کور» (brute-force) است. راهحل دوم استفاده از تکنیک «لینکهای رقصان» (Dancing Links) است. توجه داشته باشید که در این مقاله، نقطه توجه ما روی الگوریتمها است و طراحی برنامهنویسی شیءگرا چندان موضوع توجه نیست.
سودوکو به بیان ساده یک معمای ترکیبی جایگشت اعداد با شبکهای از سلولهای 9 × 9 است که بخشی از آن با اعدادی از 1 تا 9 پر شده است. هدف این است که سلولهای خالیِ باقیمانده را با بقیه اعداد طوری پر کنیم که هر ردیف و هر ستون تنها یک رقم از هر نوع داشته باشد. علاوه بر آن هر زیر بخش 3 × 3 نیز شبکه مستقلی است که نباید رقم تکراری در آن باشد. سطح دشواری سودوکو به طور طبیعی با افزایش تعداد سلولهای خالی افزایش مییابد.
برای این که راهحل خود را جالبتر کرده و الگوریتم را اعتبارسنجی کنیم از یک تخته به نام «دشوارترین سودوکوی دنیا» استفاده میکنیم که به صورت زیر است:
برای این که راهحل را نیز به سرعت افشا کرده باشیم، باید بیان کنیم که معمای به درستی حل شده نتیجه زیر را به دست میدهد:
در این بخش به بررسی الگوریتم پسگرد برای حل معمای سودوکو میپردازیم.
الگوریتم «پسگرد» (Backtracking) تلاش میکند که معما را از طریق تست کردن همه سلولها برای یک راهحل معتبر حل کند. اگر هیچ کدام از قیدهای مسئله نقض نشود، الگوریتم به سلول بعدی میرود و آن را با راهحلهای ممکن پر کرده و همه بررسیها را تکرار میکند.
اگر یک نقض قید وجود داشته باشد، در این صورت مقدار سلول را یک واحد افزایش میدهد. زمانی که مقدار سلول به 9 برسد، و همچنان راهحل معتبری یافت نشود، الگوریتم به عقب بازمیگردد و در سلول قبلی عدد مربوطه را یک واحد افزایش میدهد و این فرایند تکرار میشود. بدین ترتیب همه راهحلهای ممکن تست میشوند.
برای یادگیری بیشتر راجع به الگوریتم پسگرد، میتوانید سه مطلبی که در ادامه آمدهاند را نیز مطالعه کنید:
قبل از هر چیز باید تخته خود را به صورت آرایهای دوبعدی از اعداد صحیح تعریف کنیم. ما از مقدار 0 برای نمایش سلول خالی خود استفاده میکنیم.
در ادامه متد ()solve را ایجاد میکنیم که board را به عنوان پارامتر ورودی میگیرد و روی ردیفها و ستونها حلقهای تعریف میکند و مقادیر مختلف را برای یافتن راهحل معتبر تست میکند.
متد دیگر که نیاز داریم متد ()isValid است که به بررسی قیدهای سودوکو میپردازد، یعنی بررسی میکند آیا ردیف ستون و شبکه 3 × 3 معتبر هستند یا نه.
این سه بررسی نسبتاً مشابه هستند. ابتدا شروع به بررسی ردیفها میکنیم:
سپس از کد نسبتاً مشابهی برای اعتبارسنجی ستون استفاده میکنیم:
به علاوه باید زیربخش 3 × 3 را نیز بررسی کنیم:
در نهایت به یک متد ()checkConstraint نیاز داریم:
زمانی که همه این موارد بررسی شدند، متد ()isValid مقدار true بازگشت میدهد. اینک ما تقریباً آماده تست راهحل هستیم. کار نوشتن الگوریتم به پایان رسیده است. اما فعلاً الگوریتم صرفاً مقادیر true یا false بازگشت میدهد.
بنابراین باید به صورت چشمی تخته را بررسی کنیم تا ببینیم آیا باید نتیجه را نمایش دهیم یا نه. به ظاهر این بخشی از الگوریتم نیست.
بدین ترتیب ما موفق شدیم الگوریتم پسگرد را که به حل معمای سودوکو میپردازد پیادهسازی کنیم. بدیهی است که جا برای بهینهسازی وجود دارد، چون الگوریتم به روشی خامدستانه همه ترکیبهای ممکن را بارها و بارها بررسی میکند و ما میدانیم که برخی راهحلها اساساً نمیتوانند معتبر باشند.
در این بخش به بررسی روش لینکهای رقصنده برای حل معمای سودوکو و پیادهسازی آن در جاوا میپردازیم.
در این بخش راهحل دیگری را بررسی میکنیم. سودوکو را میتوان یک مسئله «پوشش دقیق» (Exact Cover) توصیف کرد که میتواند از طریق ماتریس وقوع نمایش یابد. این ماتریس روابط بین دو شیء را نمایش میدهد.
برای نمونه اگر اعداد 1 تا 7 را انتخاب کنیم و مجموعههایی به صورت {S = {A, B, C, D, E, F داشته باشیم که:
هدف ما این است که چنان زیرمجموعههایی را انتخاب کنیم که هر عدد تنها یک بار وجود داشته باشد و بنا به تعریف هیچ تکراری نداشته باشد. میتوان مسئله را با استفاده از یک ماتریس نمایش داد که در آن ستونها عدد و ردیفها مجموعه هستند.
زیرمجموعه {S* = {B, D, F یک پوشش دقیق است:
هر ستون دقیقاً یک عدد 1 در همه ردیفهای منتخب دارد.
الگوریتم X یک رویکرد آزمونوخطا برای یافتن همه راهحلها برای مسئله پوشش دقیق است. یعنی اگر از مجموعه مثال {S = {A, B, C, D, E, F آغاز کنیم، باید زیرمجموعه {S* = {B, D, F را بیابیم.
طرز کار الگوریتم X چنین است:
یک پیادهسازی مؤثر از الگوریتم X الگوریتم لینکهای رقصنده (به اختصار DLX) است که از سوی دکتر «دونالد نات» (Donald Knuth) پیشنهاد شده است.
بخش عمده راهحل زیر از این پیادهسازی جاوا (+) الهام گرفته است.
ابتدا باید یک ماتریس ایجاد کنیم که معمای سودوکو را به صورت یک مسئله پوشش دقیق نمایش دهد. این ماتریس 3^9 ردیف خواهد داشت یعنی برای هر موقعیت منفرد ممکن (9 ردیف × 9 ستون) از هر عدد ممکن (9 عدد) یک ردیف هست.
ستونها نماینده تخته هستند (9 × 9) که در تعداد قیدها ضرب شدهاند. همچنین سه قید نیز تعریف کردهایم:
به علاوه قید صریح چهارمی نیز وجود دارد:
بدین ترتیب در مجموع چهار قید داریم و از این رو در ماتریس پوشش دقیق، 4 × 9 × 9 ستون وجود دارند:
سپس باید تخته ذخیره ایجاد شده را بهروزرسانی کنیم تا طرحبندی اولیه معما ایجاد شود:
اینک آماده هستیم که به مرحله بعد برویم. در ادامه دو کلاس ایجاد میکنیم که سلولهای ما را به همدیگر لینک میکنند.
الگوریتم لینکهای رقصان بر مبنای این مشاهده ابتدایی عمل میکند که عملیات زیر روی لیستهای لینک شده دوطرفه از گرهها:
گره را حذف میکند و همزمان:
گره را بازیابی میکند.
هر گره در DLX به گره سمت چپ، راست، بالا و پایین خود لینک شده است. کلاس DancingNode همه عملیات مورد نیاز برای افزودن و حذف گرهها را در خود دارد:
کلاس ColumnNode ستونها را به هم لینک میکند:
در این مرحله باید یک شبکه متشکل از اشیای DancingNode و ColumnNode خود بسازیم:
ما از جستجوی شهودی برای یافتن ستونها استفاده میکنیم و زیرمجموعهای از ماتریس را بازگشت میدهیم:
در نهایت میتوانیم به صورت بازگشتی به دنبال پاسخ بگردیم:
اگر ستون دیگری باقی نمانده باشد، در این صورت میتوانیم تخته سودوکوی حلشده را در خروجی نمایش دهیم.
میتوانیم دو الگوریتم مختلف را با اجرا روی رایانه یکسان با هم مقایسه کنیم. بدین ترتیب از تأثیرگذاری تفاوت اجزای محاسباتی رایانه مانند CPU یا RAM جلوگیری میکنیم، چون زمانهای واقعی روی رایانههای مختلف متفاوت خواهد بود. با این حال، اینک میتوانیم نتایج نسبی را ببینیم و بدین ترتیب میتوان گفت که کدام الگوریتم سریعتر بود است. روی رایانهای که ما تست کردیم، اجرای الگوریتم پسگرد برای حل معما به حدود 250 میلیثانیه زمان نیاز داشت.
اگر این زمان را با زمان مورد نیاز از سوی الگوریتم لینکهای رقصان یعنی 50 میلیثانیه مقایسه کنیم، میبینیم که الگوریتم اخیر برنده این رقابت است. لینکهای رقصان در زمان حل این مثال خاص در حدود پنج بار سریعتر عمل کرده است.
در این راهنما، به بررسی دو راهحل معمای سودوکو با استفاده از توابع داخلی جاوا پرداختیم. الگوریتم پسگرد که یک الگوریتم حمله کور است میتواند معمای استاندارد 9 × 9 سودوکو را به سادگی حل کند. در ادامه الگوریتم نسبتاً پیچیدهتر لینکهای رقصان نیز مورد بررسی قرار گرفت. هر دو الگوریتم میتوانند معماهای سودوکو را در کسری از ثانیه حل کنند. در نهایت باید اشاره کنیم که کد کامل الگوریتمهای بررسی شده در این مقاله را میتوانید در این صفحه (+) مشاهده کن
منبع: فرادرس
در این مقاله قصد داریم به بررسی یک برنامه حل سودوکو و الگوریتمهای مورد استفاده از سوی آن بپردازیم. سپس این راهحلها را در جاوا پیادهسازی میکنیم. نخستین راهحل یک حمله «تهاجم کور» (brute-force) است. راهحل دوم استفاده از تکنیک «لینکهای رقصان» (Dancing Links) است. توجه داشته باشید که در این مقاله، نقطه توجه ما روی الگوریتمها است و طراحی برنامهنویسی شیءگرا چندان موضوع توجه نیست.
سودوکو به بیان ساده یک معمای ترکیبی جایگشت اعداد با شبکهای از سلولهای 9 × 9 است که بخشی از آن با اعدادی از 1 تا 9 پر شده است. هدف این است که سلولهای خالیِ باقیمانده را با بقیه اعداد طوری پر کنیم که هر ردیف و هر ستون تنها یک رقم از هر نوع داشته باشد. علاوه بر آن هر زیر بخش 3 × 3 نیز شبکه مستقلی است که نباید رقم تکراری در آن باشد. سطح دشواری سودوکو به طور طبیعی با افزایش تعداد سلولهای خالی افزایش مییابد.
برای این که راهحل خود را جالبتر کرده و الگوریتم را اعتبارسنجی کنیم از یک تخته به نام «دشوارترین سودوکوی دنیا» استفاده میکنیم که به صورت زیر است:
برای این که راهحل را نیز به سرعت افشا کرده باشیم، باید بیان کنیم که معمای به درستی حل شده نتیجه زیر را به دست میدهد:
در این بخش به بررسی الگوریتم پسگرد برای حل معمای سودوکو میپردازیم.
الگوریتم «پسگرد» (Backtracking) تلاش میکند که معما را از طریق تست کردن همه سلولها برای یک راهحل معتبر حل کند. اگر هیچ کدام از قیدهای مسئله نقض نشود، الگوریتم به سلول بعدی میرود و آن را با راهحلهای ممکن پر کرده و همه بررسیها را تکرار میکند.
اگر یک نقض قید وجود داشته باشد، در این صورت مقدار سلول را یک واحد افزایش میدهد. زمانی که مقدار سلول به 9 برسد، و همچنان راهحل معتبری یافت نشود، الگوریتم به عقب بازمیگردد و در سلول قبلی عدد مربوطه را یک واحد افزایش میدهد و این فرایند تکرار میشود. بدین ترتیب همه راهحلهای ممکن تست میشوند.
برای یادگیری بیشتر راجع به الگوریتم پسگرد، میتوانید سه مطلبی که در ادامه آمدهاند را نیز مطالعه کنید:
قبل از هر چیز باید تخته خود را به صورت آرایهای دوبعدی از اعداد صحیح تعریف کنیم. ما از مقدار 0 برای نمایش سلول خالی خود استفاده میکنیم.
در ادامه متد ()solve را ایجاد میکنیم که board را به عنوان پارامتر ورودی میگیرد و روی ردیفها و ستونها حلقهای تعریف میکند و مقادیر مختلف را برای یافتن راهحل معتبر تست میکند.
متد دیگر که نیاز داریم متد ()isValid است که به بررسی قیدهای سودوکو میپردازد، یعنی بررسی میکند آیا ردیف ستون و شبکه 3 × 3 معتبر هستند یا نه.
این سه بررسی نسبتاً مشابه هستند. ابتدا شروع به بررسی ردیفها میکنیم:
سپس از کد نسبتاً مشابهی برای اعتبارسنجی ستون استفاده میکنیم:
به علاوه باید زیربخش 3 × 3 را نیز بررسی کنیم:
در نهایت به یک متد ()checkConstraint نیاز داریم:
زمانی که همه این موارد بررسی شدند، متد ()isValid مقدار true بازگشت میدهد. اینک ما تقریباً آماده تست راهحل هستیم. کار نوشتن الگوریتم به پایان رسیده است. اما فعلاً الگوریتم صرفاً مقادیر true یا false بازگشت میدهد.
بنابراین باید به صورت چشمی تخته را بررسی کنیم تا ببینیم آیا باید نتیجه را نمایش دهیم یا نه. به ظاهر این بخشی از الگوریتم نیست.
بدین ترتیب ما موفق شدیم الگوریتم پسگرد را که به حل معمای سودوکو میپردازد پیادهسازی کنیم. بدیهی است که جا برای بهینهسازی وجود دارد، چون الگوریتم به روشی خامدستانه همه ترکیبهای ممکن را بارها و بارها بررسی میکند و ما میدانیم که برخی راهحلها اساساً نمیتوانند معتبر باشند.
در این بخش به بررسی روش لینکهای رقصنده برای حل معمای سودوکو و پیادهسازی آن در جاوا میپردازیم.
در این بخش راهحل دیگری را بررسی میکنیم. سودوکو را میتوان یک مسئله «پوشش دقیق» (Exact Cover) توصیف کرد که میتواند از طریق ماتریس وقوع نمایش یابد. این ماتریس روابط بین دو شیء را نمایش میدهد.
برای نمونه اگر اعداد 1 تا 7 را انتخاب کنیم و مجموعههایی به صورت {S = {A, B, C, D, E, F داشته باشیم که:
هدف ما این است که چنان زیرمجموعههایی را انتخاب کنیم که هر عدد تنها یک بار وجود داشته باشد و بنا به تعریف هیچ تکراری نداشته باشد. میتوان مسئله را با استفاده از یک ماتریس نمایش داد که در آن ستونها عدد و ردیفها مجموعه هستند.
زیرمجموعه {S* = {B, D, F یک پوشش دقیق است:
هر ستون دقیقاً یک عدد 1 در همه ردیفهای منتخب دارد.
الگوریتم X یک رویکرد آزمونوخطا برای یافتن همه راهحلها برای مسئله پوشش دقیق است. یعنی اگر از مجموعه مثال {S = {A, B, C, D, E, F آغاز کنیم، باید زیرمجموعه {S* = {B, D, F را بیابیم.
طرز کار الگوریتم X چنین است:
یک پیادهسازی مؤثر از الگوریتم X الگوریتم لینکهای رقصنده (به اختصار DLX) است که از سوی دکتر «دونالد نات» (Donald Knuth) پیشنهاد شده است.
بخش عمده راهحل زیر از این پیادهسازی جاوا (+) الهام گرفته است.
ابتدا باید یک ماتریس ایجاد کنیم که معمای سودوکو را به صورت یک مسئله پوشش دقیق نمایش دهد. این ماتریس 3^9 ردیف خواهد داشت یعنی برای هر موقعیت منفرد ممکن (9 ردیف × 9 ستون) از هر عدد ممکن (9 عدد) یک ردیف هست.
ستونها نماینده تخته هستند (9 × 9) که در تعداد قیدها ضرب شدهاند. همچنین سه قید نیز تعریف کردهایم:
به علاوه قید صریح چهارمی نیز وجود دارد:
بدین ترتیب در مجموع چهار قید داریم و از این رو در ماتریس پوشش دقیق، 4 × 9 × 9 ستون وجود دارند:
سپس باید تخته ذخیره ایجاد شده را بهروزرسانی کنیم تا طرحبندی اولیه معما ایجاد شود:
اینک آماده هستیم که به مرحله بعد برویم. در ادامه دو کلاس ایجاد میکنیم که سلولهای ما را به همدیگر لینک میکنند.
الگوریتم لینکهای رقصان بر مبنای این مشاهده ابتدایی عمل میکند که عملیات زیر روی لیستهای لینک شده دوطرفه از گرهها:
گره را حذف میکند و همزمان:
گره را بازیابی میکند.
هر گره در DLX به گره سمت چپ، راست، بالا و پایین خود لینک شده است. کلاس DancingNode همه عملیات مورد نیاز برای افزودن و حذف گرهها را در خود دارد:
کلاس ColumnNode ستونها را به هم لینک میکند:
در این مرحله باید یک شبکه متشکل از اشیای DancingNode و ColumnNode خود بسازیم:
ما از جستجوی شهودی برای یافتن ستونها استفاده میکنیم و زیرمجموعهای از ماتریس را بازگشت میدهیم:
در نهایت میتوانیم به صورت بازگشتی به دنبال پاسخ بگردیم:
اگر ستون دیگری باقی نمانده باشد، در این صورت میتوانیم تخته سودوکوی حلشده را در خروجی نمایش دهیم.
میتوانیم دو الگوریتم مختلف را با اجرا روی رایانه یکسان با هم مقایسه کنیم. بدین ترتیب از تأثیرگذاری تفاوت اجزای محاسباتی رایانه مانند CPU یا RAM جلوگیری میکنیم، چون زمانهای واقعی روی رایانههای مختلف متفاوت خواهد بود. با این حال، اینک میتوانیم نتایج نسبی را ببینیم و بدین ترتیب میتوان گفت که کدام الگوریتم سریعتر بود است. روی رایانهای که ما تست کردیم، اجرای الگوریتم پسگرد برای حل معما به حدود 250 میلیثانیه زمان نیاز داشت.
اگر این زمان را با زمان مورد نیاز از سوی الگوریتم لینکهای رقصان یعنی 50 میلیثانیه مقایسه کنیم، میبینیم که الگوریتم اخیر برنده این رقابت است. لینکهای رقصان در زمان حل این مثال خاص در حدود پنج بار سریعتر عمل کرده است.
در این راهنما، به بررسی دو راهحل معمای سودوکو با استفاده از توابع داخلی جاوا پرداختیم. الگوریتم پسگرد که یک الگوریتم حمله کور است میتواند معمای استاندارد 9 × 9 سودوکو را به سادگی حل کند. در ادامه الگوریتم نسبتاً پیچیدهتر لینکهای رقصان نیز مورد بررسی قرار گرفت. هر دو الگوریتم میتوانند معماهای سودوکو را در کسری از ثانیه حل کنند. در نهایت باید اشاره کنیم که کد کامل الگوریتمهای بررسی شده در این مقاله را میتوانید در این صفحه (+) مشاهده کن
منبع: فرادرس
در بخشهای قبلی این سری مقالات با مبانی کار با فرمهای HTML آشنا شدیم؛ اینک نوبت به بررسی برخی عناصر میرسد که برای ساختاردهی فرم های HTML کابرد دارند. برای مطالعه بخش قبلی این مجموعه مقالات آموزشی به لینک زیر مراجعه کنید:
هدف از این مقاله آشنایی با ساختار فرمهای HTML و معنابخشی به عناصر آن به منظور ارتقای قابلیت استفاده و دسترسپذیر ساختن آنها است.
انعطافپذیری فرمهای HTML آنها را به یکی از پیچیدهترین ساختارهای HTML تبدیل ساخته است. با استفاده از عناصر اختصاصی فرم و خصوصیتهای آنها میتوان هر نوع فرم مقدماتی را ساخت. استفاده از ساختار صحیح در زمان ساخت فرم HTML تضمین میکند که فرم هم قابل استفاده و هم دسترسپذیر باشد.
عنصر <form> رسماً یک فرم و خصوصیتهای آن را تعریف میکند که برای تعریف رفتار فرم مورد استفاده قرار میگیرد. هر بار که میخواهید یک فرم HTML ایجاد کنید، باید آن را با استفاده از این عنصر آغاز کنید و همه عناصر را داخل این تگ قرار دهید. فناوریهای حمایت از افراد کمتوان و افزونههای مرورگر زیادی وجود دارند که میتوانند عناصر <form> را کاوش کنند و قلابهای خاصی را پیادهسازی کنند تا استفاده از آنها را سادهتر کند. ما این وضعیت را در بخش قبلی مشاهده کردیم.
نکته: گنجاندن یک فرم درون فرم دیگر اکیداً ممنوع است. تعریف تودرتوی فرمها موجب میشود که به روشی غیرقابلپیشبینی و بر مبنای مرورگری که مورد استفاده قرار میگیرد، رفتار کنند.
توجه کنید که همواره میتوان از یک ویجت فرم در خارج از عنصر <form> استفاده کرد، اما اگر چنین کاری را انجام دهید، آن ویجت فرم هیچ ربطی به فرم نخواهد داشت. چنین ویجتهایی میتوانند خارج از فرم استفاده شوند، اما در این صورت باید نقشه خاصی برای چنین ویجتهایی داشته باشید، چون آنها مستقلاً کاری انجام نمیدهند و باید رفتار آنها را با جاوا اسکریپت سفارشیسازی کنید.
نکته: HTML5 خصوصیت form را روی عناصر form معرفی کرده است. بدین ترتیب میتوان یک عنصر را صراحتاً به یک عنصر اتصال داد هر چند درون <form> قرار نداشته باشد. متأسفانه در حال حاضر پیادهسازی این ویژگی روی مرورگرها آن قدر خوب نیست که بتوان به آنها تکیه کرد.
عنصر <fieldset> روشی راحت برای ایجاد گروههایی از ویجتها است که مقصود مشترکی دارند و به منظور استایلدهی یا مقاصد معناشناختی مورد استفاده قرار میگیرند. میتوانید یک <fieldset> را با گنجاندن عنصر <legend> درست زیر تگ <fieldset> برچسبگذاری کنید. محتوای متنی <legend> به طور رسمی مقصود <fieldset> که درونش قرار گرفته را توصیف میکند. فناوریهای حمایتی زیادی از عنصر <legend> به این صورت استفاده میکنند که گویی بخشی از برچسب هر ویجت درون عنصر <fieldset> است. برای نمونه برخی نرمافزارهای قرائت صفحه مانند Jaws یا NVDA محتوای legend را پیش از خواندن برچسب هر ویجت میخوانند.
در ادامه مثال کوچکی را ملاحظه میکنید:
یک نرمافزار قرائت صفحه زمانی که فرم فوق را میخواند، به صورت «Fruit juice size small» برای ویجت اول، «Fruit juice size medium» برای ویجت دوم و «Fruit juice size large» برای ویجت سوم خواهد خواند.
کاربردهای این مثال یکی از مهمترین موارد محسوب میشوند. هر بار که مجموعهای از دکمههای رادیویی داشته باشید، باید آنها را درون عنصر <fieldset> قرار دهید. کاربردهای دیگری نیز وجود دارند. به طور کلی عنصر <fieldset> میتواند برای بخشی از فرم نیز استفاده شود. به طور معمول فرمهای بلند را میتوان به چندین صفحه تقسیم کرد، اما اگر فرمی بلند باشد و حتماً باید در یک صفحه باشد، میتوان بخشهای مختلف را درون fieldset-های متفاوت قرار دارد تا شرایط استفاده از آن بهبود یابد.
عنصر fieldset به دلیل تأثیری که روی فناوری حمایتی دارد یکی از عناصر کلیدی برای ساخت فرمهای دسترسپذیر محسوب میشود. با این حال، عدم سوءاستفاده از آن در حوزه مسئولیت شما است. اگر ممکن است هر بار که یک فرم میسازید از یک نرمافزار قرائت صفحه استفاده کنید و ببینید آن را چگونه میخواند. اگر روش خواندن عجیب است میتوانید ساختار فرم را بهبود ببخشید.
چنان که در بخش قبلی این سری مقالات دیدیم، عنصر <label> روش رسمی برای تعریف یک برچسب برای یک ویجت فرم HTML محسوب میشود. اگر میخواهید فرمهای دسترسپذیر بسازید، این مهمترین عنصری است که باید استفاده کنید. زمانی که به درستی آن را پیادهسازی کنید، نرمافزارهای قرائت صفحه برچسب عنصر فرم را با دستورالعملهای مرتبط میخوانند. این مثال را که در مقاله قبلی دیدیم، در نظر بگیرید:
وقتی <label> به درستی و از طریق خصوصیتهای for و id به عنصر <input> وصل شده باشد، ابزار قرائت صفحه چیزی مانند «Name, edit text» میخواند. اگر برچسب به درستی تنظیم نشده باشد، ابزار قرائت صفحه تنها چیزی مانند «Edit text blank» میخواند که چندان مفید نیست. توجه کنید که ویجت میتواند درون عنصر <label> به صورت زیر نیز تعریف شود:
با این حال، حتی در چنین مواردی نیز بهترین رویه تنظیم خصوصیت for است، زیرا برخی فناوریهای حمایتی رابطه صریح بین برچسبها و ویجتها را درک نمیکنند.
مزیت دیگر تنظیم صحیح برچسبها این است که میتوان در همه مرورگرها برچسب را کلیک کرد تا ویجت متناظر فعال شود. این حالت به طور مثال در مورد ورودیهای متنی مفید است و میتوان روی برچسب کلیک کرد تا ورودی فوکوس پیدا کند، اما در مورد دکمههای رادیویی و کادرهای انتخاب به شدت مفید واقع میشود. مساحت قابل کلیک چنین کنترلهایی عموماً بسیار کوچک است و از این رو بهتر است آن را تا حد امکان وسعت ببخشیم. برای نمونه:
شما میتوانید چند برچسب را روی یک ویجت منفرد قرار دهید، اما این ایده خوبی نیست چون برخی فناوریهای حمایتی با آن مشکل پیدا میکنند. در مورد برچسبهای چندگانه باید یک ویجت تعریف کنید و برچسبهایش را درون یک عنصر <label> قرار دهید. به مثال زیر توجه کنید:
پاراگراف اول کد فوق قاعده عناصر الزامی را تعریف میکند. این قاعده باید در ابتدا باشد تا مطمئن باشیم که فناوریهای حمایتی مانند نرمافزارهای قرائت صفحه آن را پیش از یافتن یک عنصر الزامی نمایش داده یا بیان میکنند. بدین ترتیب این ابزارها معنی کاراکتر ستاره را میدانند. یک ابزار قرائت صفحه بسته به تنظیمات، ستارهها را به صورت Star یا Required میخواند. در هر حال هر آنچه که خوانده خواهد شد در پاراگراف اول مشخص میشود.
نکته: بسته به ابزار قرائت صفحهای که استفاده میکنید، ممکن است نتایج کمی متفاوتی به دست آورید. ما از VoiceOver (و NDVA نیز رفتار مشابهی دارد) استفاده کردهایم.
علاوه بر ساختار خاص فرمهای HTML، بهتر است به خاطر داشته باشید که این فرمها صرفاً کد HTML هستند. این بدان معنی است که میتوانید از همه توان HTML برای ساختاردهی یک فرم HTML بهره بگیرد.
چنان که در مثالهای قبلی دیدید، رویه رایج این است که برچسب و ویجت آن درون یک عنصر <div> قرار گیرد. عناصر <a> نیز کاربرد زیادی دارد. همین طور لیستهای HTML بیشتر برای ساختاردهی چند کادر انتخاب یا دکمههای رادیویی استفاده میشوند. علاوه بر عنصر <fieldset> رویه رایج این است که از عناوین HTML مانند <h1> و <h2> و قطعهبندی با استفاده از <section> برای ساختاردهی فرمهای پیچیده استفاده کنیم.
در نهایت یافتن استایل مناسب و کدنویسی آن برای طراحی یک فرم دسترسپذیر و با کارایی بالا وظیفه شماست. به طور معمول بخشهای مختلف کارکردها در عناصر <section> و دکمههای رادیویی در یک <fieldset> قرار میگیرند.
در این بخش ایدههای خود را عملیاتی میکنیم و یک ساختار فرم نسبتاً پیچیده میسازیم که یک فرم پرداخت است. این فرم شامل چند نوع ویجت است که ممکن است هنوز طرز کارشان را ندانید، اما جای نگرانی نیست، زیرا در بخش بعدی در مورد آنها توضیح خواهیم داد. فعلاً توضیحات زیر را به دقت بخوانید و شروع به درک چرایی و چگونگی استفاده از عناصر پوششی مختلف برای ساختاردهی یک فرم بکنید. در آغاز یک کپی از فایل کد HTML قالب خالی زیر روی سیستم خود ایجاد کنید:
فایل CSS فرم پرداخت ما نیز به صورت زیر خواهد بود. آن را در همان دایرکتوری فایل HTML در فایلی با نام payment-form.css ذخیره کنید:
قبل از هر چیز با افزودن کد زیر درون بخش <head> فایل HTML، تلاش کنید CSS را روی HTML اعمال کنید:
سپس شروع به افزودن عنصر <form> بیرونی بکنید:
درون تگهای <from> یک عنوان و یک پاراگراف اضافه کنید تا به کاربران اطلاع دهید که فیلدهای الزامی چگونه علامتگذاری شدهاند:
سپس یک بخش بزرگتر از کد را به فرم و زیر مدخل قبلی اضافه میکنیم. در این کد میبینید که فیلدهای اطلاعات تماس را درون یک عنصر <section> جدا قرار دادهایم. به علاوه یک مجموعه از دو دکمه رادیویی داریم که هر کدام را درون عنصر لیست (<li>) خاص خود قرار دادهایم. در نهایت دو متن استاندارد <input> داریم که به عناصر برچسب ارتباط یافتهاند. هر کدام از آنها شامل یک <p> هستند و به علاوه ورودی رمز عبور برای وارد کردن رمز عبور نیز تدارک دیده شده است. این کد را به فرم خود اضافه کنید:
اکنون به بررسی <section> دوم فرم خود میپردازیم که به اطلاعات پرداخت مربوط است. در این بخش سه ویجت متمایز داریم که هر کدام برچسبی دارند و هر یک درون یک تگ <p> قرار گرفتهاند. تگ نخست یک منوی بازشدنی (<select>) است که برای انتخاب کردن نوع کارت اعتباری استفاده میشود. تگ دوم یک عنصر <input> از نوع عدد است که برای وارد کردن شماره کارت اعتباری استفاده میشود. عنصر آخر یک <input> از نوع date است که برای وارد کردن تاریخ انقضای کارت مورد استفاده قرار میگیرد. این تگ به همراه یک ویجت انتخاب تاریخ در مرورگرهایی که پشتیبانی میکنند عرضه میشود و در مرورگرهای غیر پشتیبانیکننده به حالت همان ورودی متنی ساده درمیآید. بدین ترتیب کد زیر را در ادامه کدهای قبلی وارد کنید:
بخش آخر که اضافه خواهیم کرد بسیار سادهتر است و صرفاً شامل یک <button> از نوع submit است که برای تحویل فرم استفاده میشود. این دکمه را به فرم خود اضافه کنید:
فرم تکمیلشده را میتوانید در ادامه ملاحظه کنید.
شما اکنون تمام دانشی که برای ساختاربندی مناسب فرمهای HTML مورد نیاز است کسب کردهاید. در بخش بعدی این سری مقالات به بررسی روش پیادهسازی همه انواع مختلف ویجتهای فرم که میتوان برای گردآوری اطلاعت از کاربران مورد استفاده قرار داد خواهیم پرداخت.
منبع: فرادرس
در این مقاله، به بررسی روش مقدماتی ساخت فرم HTML میپردازیم و طراحی یک فرم ساده، پیادهسازی آن با استفاده از عناصر صحیح HTML و افزودن مقداری استایلهای مقدماتی CSS را مورد بررسی قرار داده و در مورد روش ارسال دادهها به سرور نیز صحبت خواهیم کرد. همچنین برای مطالعه قسمت قبلی این مجموعه مطلب آموزشی میتوانید روی لینک زیر کلیک کنید:
هدف از این مقاله آشنا ساختن مخاطب با ماهیت فرمهای HTML است. مخاطب با مطالعه این مقاله با کاربردهای فرم HTML، روش طراحی آنها، و عناصر ابتدایی HTML که در کاربردهای ساده نیاز خواهد داشت آشنا میشود.
فرمهای HTML یکی از مهمترین نقاط تعامل بین کاربر و یک وبسایت یا اپلیکیشن هستند. فرمهای HTML امکان ارسال دادهها به وبسایت را فراهم میسازند. در اغلب موارد این دادهها به سرور ارسال میشوند، اما یک صفحه وب نیز میتواند آنها را دریافت کرده و مورد استفاده قرار دهد.
یک فرم HTML از یک یا چند ویجت ساخته شده است. این ویجتها میتوانند فیلدهای متنی (تکخطی یا چندخطی)، کادرهای انتخاب، دکمه، کادرهای تیک، یا دکمههای رادیویی باشند. در اغلب موارد این ویجتها همراه با یک برچسب ارائه میشوند که هدف آنها را توضیح میدهد. برچسبهایی که به درستی پیادهسازی شده باشند، میتوانند هم کاربران بینا و هم نابینا را در مسیر وارد کردن ورودی در فیلد راهنمایی کنند.
تفاوت اصلی بین یک فرم HTML و یک سند معمولی HTML در اغلب موارد، دادههایی است که از سوی فرم گرداوری و به وبسرور ارسال میشوند. در این حالت باید یک وبسرور راهاندازی بکنید تا دادهها را دریافت کرده و مورد پردازش قرار دهد. شیوه راهاندازی چنین سروری فراتر از حیطه این مقاله است، اما اگر میخواهید اطلاعات بیشتری کسب کنید، پیشنهاد میکنیم با بخشهای بعدی این سری مقالات همراه شوید تا با روش ارسال دادهها به وبسرور آشنا شوید.
پیش از شروع به کدنویسی همواره بهتر است که قبل از هر کاری اندکی تأمل کرده و در مورد طراحی فرم بیندیشید. طراحی کردن سریع یک سند «نشانهگذاری» (markup) به شما کمک خواهد کرد تا مجموعه صحیحی از دادههایی را که میخواهید از کاربر بپرسید تعریف کنید. از نقطه نظر تجربه کاربر (UX) مهم است که به خاطر داشته باشید هر چه فرم بزرگتر باشد، ریسک از دست دادن کاربران بیشتر میشود. بنابراین فرم را تا حد امکان ساده و متمرکز حفظ کنید. بدین منظور باید صرفاً دادههایی را که مطلقاً ضروری هستند از کاربر بپرسید. طراحی فرم یکی از مراحل بسیار مهم ساخت یک وبسایت یا اپلیکیشن محسوب میشود. بررسی تجربه کاربری فرمها فراتر از حیطه این مقاله است، اما پیشنهاد میکنیم موارد زیر را مطالعه کنید:
در این مقاله، میخواهیم یک فرم تماس ساده بسازیم. ابتدا یک طرحواره از آن رسم میکنیم:

این فرم شامل سه فیلد متنی و یک دکمه خواهد بود. ما میخواهیم از کاربر سؤالاتی در مورد نام، ایمیل، و پیامی که میخواهید ارسال کند بپرسیم. با زدن دکمه ارسال، دادههای کاربر به وبسرور ارسال میشوند.
اینک آماده هستیم که کد HTML فرم خود را بنویسیم. برای ساخت یک فرم تماس از این عناصر HTML استفاده می کنیم: <form> ،<label> ،<input> ،<textarea> و <button>.
پیش از آنکه جلوتر برویم، ابتدا کد قالب HTML ساده زیر را کپی کرده و روی سیستم خود در فایلی به نام index.html ذخیره کنید.
همه فرمهای HTML با یک عنصر <form> به صورت زیر آغاز میشوند:
این عنصر به طور رسمی یک فرم را تعریف میکند. در واقع این عنصر کانتینری برای عناصر دیگر از قبیل <div> یا <p> است، اما از برخی خصوصیتهای ویژه برای پیکربندی رفتار فرم نیز پشتیبانی میکند. همه این خصوصیتها اختیاری هستند، اما به عنوان رویه مناسب توصیه میشود که همواره دست کم خصوصیت action و خصوصیت method تعیین شده باشند.
در حال حاضر، عنصر <form> فوق را به بدنه HTML خود اضافه میکنیم.
فرم تماس ما کاملاً ساده است و شامل سه فیلد متنی است که هر کدام یک برچسب دارند. فیلد ورودی برای نام یک فیلد متنی تکخطی خواهد بود، فیلد ورودی ایمیل یک فیلد متنی تکخطی دیگر است که صرفاً آدرس ایمیل را میپذیرد و فیلد ورودی پیام نیز یک فیلد متنی چندخطی ساده خواهد بود.
برحسب کدهای HTML باید کدی مانند زیر داشته باشیم که این ویجتهای فرم را پیادهسازی کند:
کد فرم خود را به نحوی بهروزرسانی کنید که به صورت فوق دربیاید.
عناصر <div> به آن دسته از عناصر گفته میشود که برای ساختاردهی آسانتر کد و استایلدهی سریعتر مورد استفاده قرار میگیرند. توجه داشته باید که برای همه عناصر <label> باید از خصوصیت for استفاده کنید چون این یک روش رسمی برای ایجاد ارتباط با یک ویجت فرم است. این خصوصیتِ id ویجت متناظر است. انجام این کار مزیتهایی دارد، بدیهیترین مزیت آن است که به کاربر امکان کلیک کردن روی برچسب جهت فعالسازی ویجت متناظر را میدهد. در مورد مزیتهای دیگر این خصوصیت در بخشهای بعدی این سری مقالات بیشتر صحبت خواهیم کرد.
در مورد عنصر <input>، مهمترین خصوصیت type است. این خصوصیت بسیار مهم است، زیرا روش رفتار عنصر <input> را مشخص میسازد. در بخشهای بعدی این سری مقالات در مورد این موضوع نیز بیشتر صحبت خواهیم کرد.
در انتها توجه داشته باشید که <input> با <textarea></textarea> متفاوت است. این نیز یکی از عجایب HTML است. تگ <input> یک عنصر خالی است یعنی به تگ بستن نیاز ندارد. به طور عکس <textarea> یک عنصر خالی نیست و از این رو باید تگ بستن مناسب را نیز بیاورید. این مسئله روی برخی قابلیتهای خاص فرمهای HTML مثلاً روش تعریف مقدار پیشفرض تأثیر دارد. برای تعریف مقدار پیشفرض یک عنصر <input> باید از خصوصیت value مانند زیر استفاده کنید:
به طور عکس، اگر میخواهید مقدار پیشفرض یک <textarea> را تعریف کنید، کافی است مقدار پیشفرض را بین تگهای باز و بسته عنصر <textarea> به صورت زیر قرار دهید:
فرم ما اینک تقریباً آماده است، کافی است یک دکمه به آن اضافه کنیم تا کاربر بتواند دادههایی را که در فرم وارد کرده است به ما ارسال کند. این کار به سادگی با استفاده از عنصر <button> صورت میگیرد. بنابراین کد زیر را درست بالاتر از تگ </form> وارد کنید:
بدین ترتیب خواهید دید که عنصر <button> نیز یک خصوصیت type میپذیرد. این خصوصیت سه مقدار متفاوت به صورت submit reset یا button میگیرد.
نکته: شما میتوانید از عنصر <input> با type متناظر جهت تولید دکمه نیز استفاده کنید. برای نمونه بنویسید: <input type=”submit”>. مزیت اصلی عنصر <button> این است که عنصر <input> تنها مقدار متنی ساده را مانند یک برچسب میپذیرد در حالی که عنصر <button> امکان درج HTML را دارد و میتوان متنهای خلاقانه و پیچیدهتری را نوشت.
اکنون که کار نوشتن کد HTML فرم را به پایان بردیم، تلاش میکنیم تا آن را ذخیره کرده و در یک مرورگر بررسی کنیم. در این مرحله فرم ما به صورت زیر نمایش پیدا میکند:

اگر فکر میکنید در جایی اشتباه کردهاید میتوانید کدی را که نوشتهاید با کد کامل شده زیر مقایسه کنید:
استایلدهی فرمها به طوری که زیبا به نظر رسند کار واقعاً پیچیدهای محسوب میشود. آموزش روش استایلدهی فراتر از حیطه این مقاله است و ما در اینجا صرفاً برخی کدهای مقدماتی CSS را اضافه میکنیم تا فرم مناسب به نظر بیاید.
قبل از هر چیز، یک عنصر <style> به صفحه خود اضافه کنید. این کار در بخش head سند HTML انجام مییابد و به صورت زیر خواهد بود:
درون تگهای style کد CSS زیر را وارد کنید:
اینک فرم ما به صورت زیر در آمده است و از زشتی آن کاسته شده:

در ادامه فایل کامل شده این صفحه را مشاهده میکنید:
آخرین و احتمالاً پیچیدهترین مرحله کار مدیریت دادهها در سمت سرور است. چنان که قبلاً گفتیم، در اغلب موارد یک فرم HTML روشی آسان برای دریافت دادهها از کاربر و ارسال آن به وبسرور است. عنصر <from> محل و چگونگی ارسال دادهها را به ترتیب با استفاده از خصوصیت action و خصوصیت method تعریف میکند.
اما این کافی نیست، ما باید یک نام نیز برای دادههای خود تعریف کنیم. این نامها در هر دو سمت مهم هستند. در سمت مرورگر این نام به مرورگر اعلام میکند که هر بخش از داده چه نامی دارد. در سمت سرور با استفاده از این نام میتوان هر بخش از داده را با نام آن مدیریت کرد.
برای نامگذاری دادهها در یک فرم، باید از خصوصیت name روی هر یک از ویجتهایی که اقدام به گردآوری دادهها میکنند استفاده کنیم. یک بار دیگر بخشی از کد فرم را بررسی میکنیم:
در مثال فوق، فرم 3 بخش از داده را با نامهای user_name، user_email و user_message ارسال میکند. دادهها به یک URL به صورت my-handling-form-page/ و با استفاده از متد POST در HTTP ارسال میشوند.
در سمت سرور اسکریپت در URL به نام /my-handling-form-page دادهها را به صورت لیستی از 3 آیتم کلید/مقدار دریافت میکند که در درخواست HTTP جاسازی شدهاند. روش مدیریت دادهها از سوی اسکریپت بر عهده شما است. هر زبان سمت سرور مانند PHP، پایتون، روبی، جاوا، سی شارپ و غیره به این منظور سازوکار خاص خود را دارند. بررسی دقیق این موضوع خارج از حوصله این مقاله است.
اینک شما موفق شدهاید نخستین فرم HTML خود را بسازید که به صورت زیر نمایش مییابد:
این تنها آغاز کار است و اینک زمان آن رسیده است که نگاهی عمیقتر به موضوع داشته باشیم. فرمهای HTML بسیار قدرتمندتر از آن چیزی هستند که در این مقاله بررسی کردیم. در بخشهای بعدی این سری مقالات به بررسی دقیقتر آنها میپردازیم. برای مطالعه بخش بعدی به لینک زیر رجوع کنید:
منبع: فرادرس
در این بخش از سری مقالات ساخت اپلیکیشن آیفون یک فریمورک به پروژه خود اضافه میکنیم تا کامپوننتهایی عرضه کنیم که از نظر بصری سفارشیسازی بیشتری داشته باشند. کدهای این کامپوننتها قبلاً نوشته شده است. در بخش قبلی یک طرحبندی سلول سفارشی را با استفاده از ابزارهای دیداری اینترفیسساز ساختیم. برای مطالعه بخش قبلی به لینک زیر رجوع کنید:
یکی از مهمترین اهداف این سری مقالات آموزشی این است که یک اپلیکیشن را تا حد امکان با استفاده از ابزارهای دیداری بسازیم، و در عین حال کمترین کد ممکن را نیز بنویسیم. ابزارهای دیداری مانند هر چیز دیگری در دنیای رایانه (شامل گوشیهای هوشمند) تنها زمانی کار میکنند که فرد دیگری کدهایی را در پشت صحنه نوشته باشد. تا به اینجا ما روی استفاده از «اینترفیسساز» (Interface Builder) مربوط به Xcode متمرکز شدهایم که یک ابزار دیداری برای ویرایش طرحبندی است. در اینترفیسساز میتوانیم نماها را بکشیم و خصوصیتها را تعیین کنیم، چون فرد دیگری قبلاً کد مربوط به کارکرد اینها را نوشته است.
برای تنظیم فریمورک به گیت اعلام میکنیم که آن را از ریپازیتوری مربوطه روی اینترنت به صورت محلی برای ما کلون کند.
ما در این راهنما استفاده زیادی از فناوریهای مختلف داشتهایم. این فرایند نیز سرراست و سریع است. ما همه گامها را به دقت توصیف کردهایم، چون این یک سرزمین کاملاً جدید است.
در انتهای این راهنما، تغییرها را با استفاده از سیستم کنترل نسخه Git کامیت میکنیم. پروژه ما در ریپازیتوری مربوط به خود قرار دارد. گیت از طریق استفاده از «ماژولهای فرعی» (Submodules) ریپازیتوریهای دیگر در پروژه اصلی، برخی تسهیلات دیگر را نیز در اختیار ما قرار میدهد تا تاریخچه نسخه برای هر کدام به صورت جداگانه مدیریت میشود.
ما قصد داریم فریمورک BFWControls را به پروژه خود اضافه کنیم. این کار نیازمند سه گام زیر است:
در Xocde روی فایل پروژه آبیرنگ در ابتدای بخش ناوبری پروژه Control+Click کنید. گزینه New Group را از منوی بازشدنی انتخاب کنید.

Xcode یک گروه جدید (یک آیکون پوشه زردرنگ) با نام New Group ایجاد میکند. یک بار روی نام کلیک کنید تا name را به حالت ویرایش درآورد.

این نام را به Submodules تغییر دهید. گروه Submodules را به سمت پایین بکشید و تا قبل از گروه Submodules بیاورید.

مواظب باشید که آن را درون گروه دیگری نکشید، اما اگر چنین اتفاقی افتاد، میتوانید آن را دوباره به مکان صحیح درگ کنید. روی گروه جدید Submodules همراه با فشردن کلید Control کلیک کنید و گزینه Show in Finder را در منوی بازشدنی انتخاب کنید.

اپلیکیشن Terminal را روی مک باز کنید. آن را میتوانید در پوشه Applications بیابید. در ترمینال ابتدا باید دایرکتوری را عوض کنیم و به پوشه جدید Submodules برویم. بدین منظور در پنجره ترمینال، دستور cd را وارد کنید و یک فاصله بدهید:

اینک باید مسیر پوشه Submodules را بدانیم. به جای وارد کردن آن کافی است پوشه Submodules را از Finder به پنجره ترمینال کشیده و رها کنید.

بدین ترتیب مسیر پوشه در ترمینال ظاهر میشود.

دکمه Return را بزنید تا به ترمینال اعلام کنید که دستور را اجرا کند.

ما باید یک دستور دیگر در ترمینال وارد کنیم تا به گیت اعلام کنیم که ماژول فرعی BFWControls را به این پوشه اضافه کند. به این منظور باید URL مربوط به ریپازیتوری BFWControls را بدانیم. از مرورگر وب استفاده کنید تا به دنبال BFWControls بگردید. دو نتیجه اول معمولاً وبسایتهای github.com و bitbucket.org هستند.

این سایتها ریپازیتوریهایی برای استفاده عمومی و خصوصی میزبانی میکنند. BFWControls یک ریپازیتوری عمومی و متنباز است یعنی هر کسی میتواند از آن استفاده کند و حتی کدهایی برای بهبود آن بنویسید و با درخواست pull کد مربوط به تغییراتی که ایجاد کرده است را در پروژه ادغام کند.
روی لینک گیتهاب کلیک کنید. بدین ترتیب به صفحه گیتهاب BFWControls میروید که شامل لینکهایی برای کامیتها، فایلها و موارد دیگر است. ما با هیچکدام اینها کاری نداریم. تنها چیزی که نیاز داریم لینک این ریپازیتوری است.
در سمت راست روی دکمه Clone or Download کلیک کنید، بدین ترتیب URL-ی نمایش پیدا میکند که شامل لینک به ریپازیتوری است. در سمت راست متن لینک، یک دکمه برای کپی کردن آن وجود دارد. روی دکمه کلیک کنید. البته میتوانید متن لینک را به صورت دستی نیز انتخاب و کپی کنید:

به ترمینال بازگردید و در ابتدای دستور خود عبارتهای زیر را وارد کنید:
git submodule add
مطمئن شوید که پس از آخرین کلمه یک فاصله وجود دارد و سپس گزینه Paste را از منوی Edit انتخاب کنید تا دستور تکمیل شود.

دکمه Return را بزنید. گیت اقدام به کلون کردن ریپازیتوری در پوشه Submodules که ایجاد کردهایم میکند.

بدین ترتیب کار ما در ترمینال پایان یافته است و میتوانید آن را ببندید. کار ما با وبسایت گیتهاب نیز تمام شده و میتوانید برگه مربوطه مرورگر را ببندید؛ بدین ترتیب ما با موفقیت ریپازیتوری BFWControls را به عنوان یک ماژول فرعی در ریپازیتوری خود اضافه کردیم.
نگاهی به پوشه Submodules در Finder داشته باشید. این پوشه هم اکنون یک پوشه دیگر به نام BFWControls نیز دارد. آن را باز کنید تا فایل BFWControls.xcodeproj را ببینید. این فایل پروژه است و باید به پروژه Xcode اضافه شود.

فایل BFWControls.xcodeproj را از Finder دوباره به Xcode و گروه Submodules بکشید.

فایل BFWControls.xcodeproj اینک باید در پروژه Xcode نمایش یافته باشد.

اکنون ما پروژه BFWControls Xcode را به پروژه خود اضافه کردهایم. پروژه BFWControls یک framework برای ما ایجاد میکند که میتواند از سوی اپلیکیشنهای دیگر مانند اپلیکیشن ما مورد استفاده قرار گیرد. اکنون کافی است به پروژه اعلام کنیم که از این فریمورک استفاده کند.
یک بار روی آیکون آبی پروژه در Project Navigator کلیک کنید. مطمئن شوید که آیکون اپلیکیشن زیر برگه Targets و General انتخاب شده است.

پنل بزرگ میانی را اسکرول کنید تا به بخش Embedded Binaries برسید. روی دکمه + زیر آن کلیک کنید.

در لیستی که نمایان میشود، گزینه فوقانی BFWControls.framework را انتخاب کنید. دقت کنید گزینه BFWControls Demo.app را انتخاب نکنید.

روی دکمه Add کلیک کنید؛ Xcode در این مرحله BFWControls.framework را به Embedded Binaries و Linked Frameworks اضافه میکند.

اپلیکیشن را اجرا کرده و بررسی کنید که آیا همه بیلدها و اجراها مانند قبل هستند یا نه. احتمالاً متوجه خواهید شد که زمان build اولیه طولانیتر شده است، چون کد BFWControls نیز ساخته میشود.
البته با باز کردن اپلیکیشن هنوز از فریمورک استفاده نکردهاید، اما در ادامه قصد انجام این کار را داریم.
همانند بخشهای قبلی در انتهای مقاله تغییرهایی را که در پروژه ایجاد کردهایم، کامیت میکنیم تا ذخیره شوند. به این منظور:
نکته: فایلهای تغییر یافته روی رایانه شما ممکن است کمی متفاوت باشند.

اپلیکیشن ما هم اینک ماژول فرعی BFWControls را دارد که در Git یکپارچه شده است و BFWControls.framework حاصل نیز با استفاده از Xcode در اپلیکیشن ما ادغام شده است. ما در بخش قبلی (هفتم) یک طرحبندی برای سلول نمای جدولی در یک فایل جدید به نام NewsTableViewCell ساختیم در بخش بعدی (نهم) از BFWControls.framework برای بارگذاری طرحبندی سلول سفارشی در استوریبورد استفاده خواهیم کرد. برای مطالعه بخش بعدی به لینک زیر رجوع کنید: