مشاوره رایگان
دریافت لینک های دانلود دریافت پستی درب منزل مبلغ کل: تومان
جهت دریافت کد تخفیف به کانال تلگرام مراجعه و یا با پشتیبان آنلاین هماهنگ نمایید

جلسه دوازدهم آموزش iOS : نحوه افزودن Search Bar در Table Viewها


در این جلسه ، قصد داریم ، نحوه افزودن نوار جستجو (Search Bar) ، را به پروژه Tab Bar ، آموزش دهیم. با استفاده از ابزار Search Bar ، کاربران اپ، اجازه دارند که در لیست دستور پخت ها، با تعریف یک آیتم جستجو، عملیات جستجو را انجام دهند.
افزودن Search Bar ، کار دشواری نیست. برای این منظور ، کار روی پروژه Xcode  خود را که در جلسه قبل آموزش داده ایم، ادامه خواهیم داد.


 

آشنایی با Search Display Controller

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

همانند سایر view controllerها ، می توانیم از طریق برنامه نویسی ، search display controller را ایجاد کنیم و یا به سادگی ، آن را به اپ خود ، با استفاده از Storyboard ، اضافه کنیم. در این آموزش ، ما از رویکرد دوم استفاده خواهیم کرد.

افزودن Search Display Controller در Storyboard

در Storyboard ، کنترلر “Search Bar and Search Display Controller” را درست زیر navigation bar ، از قسمت Recipe Book View Controller ، درگ کرده و اضافه می کنیم. اگر به درستی ، کار انجام شود، صفحه نمایش باید شبیه تصویر زیر باشد:


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

با این که ما هنوز کاری انجام نداده ایم، چرا نتایج جستجو ، همه دستور پخت ها را نشان می دهد؟

همان طور که قبلاً ذکر شد ، نتایج جستجو در table view که توسط search display controller ، ایجاده شده، نمایش داده می شود. هنگام توسعه اپ table view ، ما پروتکل UITableViewDataSource را اجرا کردیم ، تا تعداد ردیف ها و داده های هر ردیف از جدول را به Table View، اعلام کنیم.


مانند UITableView ، table view ایجاد شده توسط search display controller ، نیز چنین رویکردی را اتخاذ می کند. با مراجعه به مستند رسمی UISearchDisplayController ، می توان فهمید که نمایندگانی (delegates) در دسترس هستند، که به ما اجازه می دهند ، با نتایج جستجو و search bar ارتباط برقرار کنیم.

به طور معمول ، original view controller ، به عنوان source object ، برای منبع داده های مربوط به نتایج جستجو و نمایندگی ، مورد استفاده قرار می گیرد. نیازی نیست که به صورت دستی ارتباط بین منبع داده ها و نمایندگی ها ، با view controller ، برقرار شود. در حین این که، نوار جستجو را به نمایشگر (view) ، مربوط به Recipe Book View Controller ، اضافه می کنیم، ارتباطات لازم با search display controller ، به صورت خودکار، پیکربندی می شود. می توانیم برای مشاهده ارتباطات ، کلید کنترل صفحه کلید را فشار داده و روی گزینه “Search Display Controller” کلیک کنیم.


هر دو مورد table view ها (یعنی table view در Recipe Book View Controller و table view مربوط به نتایج جستجو) ، view controller یکسانی را جهت پر کردن داده های جدول، به اشتراک می گذارند. به همین دلیل است که نتایج جستجو، لیست کاملی از دستور پخت ها را بدون در نظر گرفتن، عبارت مورد جستجو، نشان می دهد.

اگر به بخش کد، مراجعه کنیم، دو متد وجود دارند که در هنگام نمایش داده های جدول فراخوانی می شوند.
 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [recipes count];
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"RecipeCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }
    
    cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
    return cell;
}

 

پیاده سازی جستجو

برای پیاده سازی عملیات جستجو، دو مورد وجود دارند که باید آنها را پیاده سازی کرده و تغییر دهیم.

  1. پیاده سازی متدهایی برای جست و جو  کردن نام دستور پخت ها و بازگرداندن نتایج صحیح برای جستجو.
  2. تغییر متد data source ، برای تفاوت قائل شدن بین table viewها. اگر متغیر tableView ، به table view مربوط به Recipe Book View Controller، پاس داده شود، همه دستور پخت ها را نشان می دهیم. در سمت دیگر، اگر table view ، مربوط به نتایج جستجو باشد ، فقط نتایج جستجو ، نمایش داده می شوند.

ابتدا ، ما نحوه پیاده سازی جستجو را نشان خواهیم داد. در اینجا ، ما یک آرایه داریم که تمام دستور پخت ها را ذخیره می کند. آرایه دیگری جهت ذخیره سازی نتایج جستجو، ایجاد کرده و نام آن را “searchResults” قرار می دهیم.

 

@implementation RecipeBookViewController {
    NSArray *recipes;
    NSArray *searchResults;
}

 

در ادامه، یک متد جدید ، برای مدیریت کردن جستجو ، اضافه می کنیم. جست و جو از طریق محدود کردن نتایج، یکی از روال های متداول ، در اپ های iOS می باشد. روش سرراست برای جست و جو کردن لیست دستور پخت ها، استفاده از حلقه loop برای تمام نام ها و فیلتر کردن نتایج ، با عبارت if-statement ، می باشد. چنین پیاده سازی، هیچ ایرادی ندارد. اما ، iOS SDK، یک روش بهتر ، به نام Predicate را برای مدیریت کردن پرس و جو های (queries) عملیات جستجو ، پیشنهاد می دهد. با استفاده از NSPredicate (که یک شیء representation مربوط به predicate می باشد)، ما کد کمتری خواهیم نوشت.  فقط با دو خط کد، NSPredicate، جستجو را در بین تمام دستور پخت ها انجام داده و نتایج منطبق را ، باز می گرداند.

 

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate 
                                    predicateWithFormat:@"SELF contains[cd] %@",
                                    searchText];
    
    searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}

 

اساساً، یک predicate، عبارتی است که مقدار Boolean (true یا false) را بر می گرداند. ما معیار جستجو را در فرمت NSPredicate مشخص می کنیم و از آن برای فیلتر کردن داده ها در آرایه ، استفاده می نماییم. NSArray ، متد filteredArrayUsingPredicate: method را فراهم می کند ، که این متد ، یک آرایه جدیدی ، که حاوی اشیائی است که predicate مشخص شده را تطبیق می دهد، باز می گرداند. کلید واژه  SELF ، در predicate “SELF contains[cd] %@”، به اشیایی که مورد ارزیابی قرار گرفته اند (یعنی دستور پخت ها) اشاره دارد. عملگر “[cd]”، به این معنی است که، مقایسه ، غیر حساس به حروف کوچک و بزرگ و تفکیک کننده ها (case- and diacritic-insensitive) می باشد.
اگر می خواهید اطلاعات بیشتری در مورد Predicate، بدست آورید، مستند
 Apple’s official documentation یا  the tutorial written by Peter Friese را بررسی کنید.
 

پیاده سازی نماینده Search Display Controller

تا اینجا ، ما یک متد برای مدیریت کردن جت و جوی داده ها ، ایجاد کرده ایم. اما ، چه موقع ، این متد باید فراخوانی شود؟ ظاهراً متد filterContentForSearchText: method ، وقتی فراخوانی می شود که کاربر ، عبارت مورد نظر خود را جستجو می کند. کلاس UISearchDisplayController ، با یک متد shouldReloadTableForSearchString: method ، همراه است که به طور خودکار هر دفعه که رشته مورد جستجو تغییر می یابد، فراخوانی می شود. بنابراین، متد زیر را در فایل RecipeBookViewController.m، اضافه می کنیم.
 

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller 
shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString 
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];
    
    return YES;
}

 

نمایش دادن نتایج جستجو در searchResultsTableView

همان طور که قبلاً شرح داده شد، ما باید در متدهای data source، جهت ایجاد تمایز بین table viewها، تغییر ایجاد نماییم. ایجاد تمایز در table viewها ، کار راحتی می باشد. ما به سادگی ، شیء tableView را با “searchResultsTableView” که از مؤلفه های “searchDisplayController” می باشد، مقایسه می کنیم. اگر نتیجه مقایسه مثبت باشد ، ما نتایج جستجو را به جای تمام دستور پخت ها نشان می دهیم. تغییرات اعمال شده در دو متد، عبارتند از:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [searchResults count];
 
    } else {
        return [recipes count];
        
    }
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"RecipeCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }
    
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
    } else {
        cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
    }
    
    return cell;
}

 

تست دوباره اپ

هنگامی که تغییرات فوق را کامل نمودیم، اپ خود را دوباره تست می نماییم. اکنون ، نوار جستجو ، باید به درستی کار کند.

مدیریت کردن انتخاب ردیف در نتایج جستجو

با وجود این که عملیات جستجو کار می کند، اما هنوز ، به عمل انتخاب کردن ردیف، پاسخی نمی دهد. ما می خواهیم، انتخاب ردیف ، مانند table view دستور پخت ، عمل کند. به این ترتیب که ، هنگامی که کاربر ، بر روی هر کدام از نتایج جستجو ، ضربه بزند ، detail view ، نام دستور پخت را نشان دهد.
پیش تر، ما از Segue ، برای پیوند دادن سلول جدول دستور پخت و  detail view ، استفاده کردیم.
واضح است که ما باید ، Segue دیگری را در Storyboard ، ایجاد کنیم ، تا انتقال اطلاعات ، بین نتایج جستجو و detail view را انجام دهد. مشکل در این جاست که ما نمی توانیم این کار را انجام دهیم. table view مربوط به نتایج جستجو، یک متغیر ویژه از search display controller می باشد. مدیریت کردن انتخاب ردیف در نتایج جستجو با استفاده از Storyboard غیرممکن است.
با این حال، search display table view، به ما اجازه می دهد تا با استفاده از نماینده، با انتخاب کاربر ، در جدول نتایج، ارتباط برقرار کنیم. هنگامی که کاربر ، یک ردیف را انتخاب می کند، متد didSelectRowAtIndexPath: method ، فراخوانی خواهد شد. بنابراین ، آن چه که ما باید انجام دهیم ، پیاده سازی این متد می باشد:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        [self performSegueWithIdentifier: @"showRecipeDetail" sender: self];        
    }
}

 

ما به سادگی ، متد performSegueWithIdentifier: method را برای راه اندازی دستی Segue مربوط به ”showRecipeDetail” فراخوانی می کنیم. قبل از ادامه، سعی می کنیم اپ را دوباره اجرا کنیم. زمانی که کاربر، هر کدام از نتایج جستجو را انتخاب کند، اپ ، detail view ، را که حاوی نام دستور پخت می باشد ، نشان می دهد. اما، این نام، همیشه درست نیست.

ما از متد “indexPathForSelectedRow” ، برای بازیابی indexPath ، مربوط به ردیف انتخاب شده، استفاده می کنیم. همان طور که قبلاً ذکر شد ، نتایج جستجو ، در یک table view جداگانه، نمایش داده می شوند. اما، در فرمت اصلی متد prepareForSegue: method ، ما همیشه، ردیف انتخاب شده را ، از table view مربوط به Recipe Book View Controller ، بازیابی می کنیم. به همین دلیل، نام دستور پخت اشتباه ، در detail view، دیده می شود. برای داشتن نتایج جستجو صحیح، ما باید ، متد prepareForSegue: method را کمی تغییر دهیم:


	- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showRecipeDetail"]) {
        RecipeDetailViewController *destViewController = segue.destinationViewController;
        
        NSIndexPath *indexPath = nil;
 
        if ([self.searchDisplayController isActive]) { 
            indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
            destViewController.recipeName = [searchResults objectAtIndex:indexPath.row];
            
        } else {
            indexPath = [self.tableView indexPathForSelectedRow];
            destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
        }
    }
    
}

 

ابتدا، باید مشخص کنیم که آیا کاربر، از عملیات جستجو استفاده می کند. هنگام جستجو ، ما indexPath را از searchResultsTableView ، بازیابی می کنیم ، که ببینیم آیا indexPath مربوط به Table view ، نتایج جستجو می باشد یا خیر. در صورتی که indexPath مربوط به Table view نتایج جستجو نباشد ، ما فقط ، indexPath مربوط به table view ، کنترلر Recipe Book View Controller، را دریافت می کنیم.

بسیار خوب! اپ را مجدداً اجرا می کنیم. انتخاب ردیف مربوط به نتایج جستجو، باید به همان صورتی که انتظار داریم، عمل کند. به این صورت که ، با انتخاب یک ردیف از نتایج جستجو شده، صفحه جزئیات مربوط به آن ردیف ، باز شده و نام دستور پخت در آن نشان داده شود.


امیدواریم که این آموزش برای شما مفید واقع شده باشد. جلسه بعدی ما را دنبال کنید!
 

فصلِ: 3 , تعداد قسمت ها: 179 , سطح: صفر تا صد

این فصل در یک نگاه:

در این دوره آموزشی ، برنامه نویسی اندروید و ios را با استفاده از زامارین خواهیم آموخت. همچنین به صورت کاملا پروژه محور ، اپلیکیشن فروشگاهی مشابه دیجی کالا را پیاده سازی خواهیم کرد. در انته…
فصلِ: 5 , تعداد قسمت ها: 221 , سطح: صفر تا صد
موضوعات: آموزش IOS

این فصل در یک نگاه:

در این فصل:-نمایش notification به کاربر زمانی که اتفاقاتی از قبیل لایک کردن پست و ... میافتد(این مبحث مبحثی مهم بوده و ج…

  توضیحات کلی دوره: با سلام خوش اومدین به حرفه ای ترین دوره ی Swift ابتدای کار ممکن است سوالی برای شما پیش آید: -من نیازی به ساخت اپلیکیشن اجتماعی ندارم چرا باید این دوره را ببینم؟ ج…
فصلِ: 7 , تعداد قسمت ها: 159 , سطح: صفر تا صد
موضوعات: آموزش IOS

این فصل در یک نگاه:

اپل نویس حرفه ای شوید... با این پکیج کسب درآمد میلیونی کنید....   در این پکیج به نکات ریز و درشت زیادی پرداختیم که خیلی خیلی میتونه به شما کمک کنه که تبدیل به برنامه نویس حرفه ای شوید... …
فصلِ: 12 , تعداد قسمت ها: 126 , سطح: صفر تا صد
موضوعات: آموزش IOS

این فصل در یک نگاه:

فصل 16 فصل آخرمون هست و میایم توی این فصل یه سری مباحث کوچیکی که جامونده و کارهای نهایی برای انتشار برنامه توی مایکت های…

با سلام نکته:هیچ نیازی به mac و یا iphone نیست... نکته:هیچ نیازی به بلد بودن برنامه نویسی از قبل نیست... مباحثی که توی این دوره مرور میکنیم میتونه ما رو از سطح صفر برنامه نویسی ios به صد …
فصلِ: 6 , تعداد قسمت ها: 194 , سطح: صفر تا صد

این فصل در یک نگاه:

در این فصل آپدیت های مربوط به دوره را قرار میدهیم…

با سلام و خسته نباشد خدمت کلیک سایتی های عزیز در ادامه با توضیحات مختصری درمورد دوره ی react native با ما همراه باشید: React Native چیست؟ قطعا یکی از آرزوهای برنامه نویسان این میباشد که ب…
فصلِ: 5 , تعداد قسمت ها: 51 , سطح: صفر تا صد

این فصل در یک نگاه:

اموزش پرداخت درون برنامه ای بازار در یونیتی-اموزش خرید سکه در بازی-اموزش خرید مصرفی و غیر مصرفی…

توضیحات کلی مجموعه: آموزش مقدماتی تا پیشرفته یونیتی(ساخت بازی توپ چرخنده-اموزش بازی دوبعدی-اموزش بازی سه بعدی اول شخص شوتر-اموزش بازی سه بعدی رالی (ماشین سواری))   سرفصلهای دوره: نصب ی…
فصلِ: 2 , تعداد قسمت ها: 68 , سطح: صفر تا صد

این فصل در یک نگاه:

آموزش ساخت یک فروشگاه کوچک-آموزش کار با bottom navigation -آموزش کار با تب بار-آموزش کار با scrollview - آموزش کار با ان…

توضیحات کلی مجموعه: آموزش دوره فلاتر از پایه تا پیشرفته(این دوره به دوره متخصص فلاتر تغییر پیدا کرد) درسال های گذشته تعدا زیادی فریمورک معرفی شد که هرکدام تجربه خاص خودش رو داشت،اما فلاتر …
فصلِ: 5 , تعداد قسمت ها: 25 , سطح: صفر تا صد

این فصل در یک نگاه:

فصل پنجم…

توضیحات کلی مجموعه: درباره گیت: لذت پیش بردن پروژه های برنامه نویسی خود را با بهترین ورژن کنترل سیستم جهان تجربه کنید کامل ترین دوره ی آموزشی گیت و گیت هاب به همراه مثال های کاربردی گی…

تولید شده توسط کلیک سایت

پشتیبانی آنلاین
آماده پاسخگویی هستیم
انتخاب تصویر جهت ارسال:
در حال ضبط صدا

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

توقف و ارسال :
لغو ضبط
در حال حاضر تمامی کارشناسان آفلاین هستند. همواره می توانید با شماره تلگرام / واتساپ 09010005000 به صورت آنلاین با ما در ارتباط باشید. جهت ورود به واتساپ کلیک کنید
0 پیام جدید
پشتیبان در حال تایپ ...
ارسال تصویر ضبط صدا
0 کارشناسان آنلاین می باشند
این گفت و گو توسط پشتیبان به اتمام رسید