2012-03-10 12 views
17

tôi đang tìm kiếm thực hiện một UISearchBar mà lấy thông tin từ một url, và với phương pháp mặc định:UISearchBar phát hiện khi loại người dùng dừng lại và không tìm kiếm ngay lập tức để phát hiện tạm dừng

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ 

tôi có thể phát hiện ngay lập tức khi thay đổi văn bản và thực hiện tìm nạp url, nhưng theo cách này, kiểu văn bản chậm vì iPhone đang tìm kiếm url, vì vậy tôi muốn bắt đầu tìm nạp url khi người dùng ngừng viết trong giây lát, vì vậy tôi muốn phát hiện tạm dừng nhập để làm mới chế độ xem bảng truy xuất thông tin theo url. tôi đã tìm thấy một bài đăng cũ của yêu cầu này và tôi đã thử một giải pháp mà đối với tôi không làm việc:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(request:)  object:searchText]; 

    //..... 

    [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; 
} 

-(void)request:(NSString *)myString 
{ 
    NSLog(@"%@",myString); 
} 

theo cách này khi tôi đang gõ phương thức yêu cầu không được gọi nhưng khi tôi dừng lại gõ nó được gọi cho mọi loại ký tự i, vì vậy cũng giống như phương pháp mặc định, tôi đã làm sai điều gì đó? hoặc việc triển khai không chính xác?

Trả lời

24

Dường như các giải pháp cung cấp không làm việc vì "searchText" lập luận để cancelPreviousPerformRequestsWithTarget:selector:object: không khớp với đối số "searchText" cho cuộc gọi trước đó tới performSelector:withObject:afterDelay:; các tìm kiếm bị trì hoãn sẽ được xếp hàng đợi theo mọi thay đổi văn bản và không bao giờ bị hủy.

Bạn có thể sử dụng NSTimer để trì hoãn yêu cầu tìm kiếm và hủy hẹn giờ bất cứ khi nào văn bản thay đổi: Cung cấp cho đối tượng của bạn thuộc tính hoặc trường NSTimer; trong searchBar:textDidChange: hủy mọi bộ hẹn giờ hiện có, sau đó tạo và lên lịch bộ hẹn giờ mới. Mục tiêu của bộ hẹn giờ nên gọi phương thức tìm kiếm của bạn.

Giống như (ra khỏi đỉnh đầu của tôi):

// in your class' .h object fields 
{ 
    ... 
    NSTimer *searchDelayer; // this will be a weak ref, but adding "[searchDelayer invalidate], searchDelayer=nil;" to dealloc wouldn't hurt 
    ... 
} 

// in the .m 

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [searchDelayer invalidate], searchDelayer=nil; 
    if (YES /* ...or whatever validity test you want to apply */) 
    searchDelayer = [NSTimer scheduledTimerWithTimeInterval:1.5 
                target:self 
                selector:@selector(doDelayedSearch:) 
                userInfo:searchText 
                repeats:NO]; 
} 

-(void)doDelayedSearch:(NSTimer *)t 
{ 
    assert(t == searchDelayer); 
    [self request:searchDelayer.userInfo]; 
    searchDelayer = nil; // important because the timer is about to release and dealloc itself 
} 

Một số lập trình viên có thể ít ung dung về tài liệu tham khảo yếu hơn là tôi đang ở đây.

[chỉnh sửa để thêm:]

Đây là cách bạn có thể làm điều đó nếu bạn đã được thiết lập về việc sử dụng cancelPreviousPerformRequestsWithTarget ...:

// in your class' .h object fields 
{ 
    ... 
    NSString *priorSearchText; // this will NOT be a weak ref, so adding "[priorSearchText release]" to dealloc is also required 
    ... 
} 

// in the .m 
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [NSObject cancelPreviousPerformRequestsWithTarget:self 
              selector:@selector(request:) 
              object:priorSearchText]; 
    [priorSearchText release], priorSearchText = [searchText retain]; 
    if (YES /* ...or whatever validity test you want to apply */) 
    [self performSelector:@selector(request:) 
       withObject:searchText 
       afterDelay:1.5]; 
} 

Tôi không nghĩ rằng tôi đã từng sử dụng cancelPreviousPerformRequestsWithTarget: ... cho thực, vì vậy tôi không biết nếu nó ẩn bất kỳ bất ngờ. Nếu bạn gặp sự cố, hãy thêm NSLogs, tìm kiếm các tìm kiếm bị trì hoãn không bị hủy khi cần.

+0

cách bạn triển khai tùy chọn đầu tiên với NSString? bạn có thể viết một ví dụ mã không? – Piero

+0

ok, tôi sẽ viết thứ gì đó lên. Không được bảo đảm để làm việc không có lỗi mặc dù, vì tôi đã không thử phương pháp này trong mã thực. – rgeorge

+0

dòng này đang làm gì? [tự yêu cầu: searchDelayer.userInfo]; ? –

0

Move dòng này: [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; ra khỏi phương pháp textDidChange bạn và đặt nó trong văn bản đã bắt đầu phương pháp chỉnh sửa: - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar

+0

nhưng nếu tôi thêm dòng đó vào phương thức này: - (void) searchBarTextDidBeginChỉnh sửa: (UISearchBar *) searchBar ở đây không có đối số searchText, cách tôi có thể thực hiện ... – Piero