UISearchController和UISearchBar子类化

3

你好。

我在使用自定义的UISearchController子类VLSearchController时出现了问题,它带有一个自定义的UISearch Bar,在我的UIViewController中无法调用任何委托方法。我的自定义子类没有自己的委托方法,但我认为由于它们是子类... 它们的委托方法也将被继承,并且需要在初始化UISearchController的UIViewController中定义。

在初始化UISearchController后,我将其委托和搜索栏的委托都设置为UIViewController:

_searchController = [[VLSearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchBar.delegate = self; 
self.searchController.delegate = self;

在我的UIViewController中,以下委托方法没有被调用:

#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;

#pragma mark - UISearchController
- (void)willPresentSearchController:(UISearchController *)searchController;

#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController;

让我也提一下,我对UISearchController和UISearchBar进行子类化的原因是为了去掉取消按钮。 我需要给子类添加代理方法吗?如果需要,是否可以有人解释一下这些代理方法会做什么?
编辑:添加代码
UIViewController:
-(void) viewDidLoad
{

    [super viewDidLoad];

    //// Search & Results Stuff
    _searchController = [[VLSearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;

    [self.searchController.searchBar sizeToFit];
    self.searchController.searchBar.barTintColor = UIColorFromRGB(0x411229);

    [self.sfView addSubview:self.searchController.searchBar];

    self.searchController.delegate  = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;
    self.definesPresentationContext = YES;
} 

- (void)viewDidAppear:(BOOL)animated 
{

    [super viewDidAppear:animated];

    if (self.searchControllerWasActive) {
        self.searchController.active = self.searchControllerWasActive;
        _searchControllerWasActive = NO;

        if (self.searchControllerSearchFieldWasFirstResponder) {
            [self.searchController.searchBar becomeFirstResponder];
            _searchControllerSearchFieldWasFirstResponder = NO;
        }
    }
}

#pragma mark - UISearchBarDelegate

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{
    [searchBar resignFirstResponder];
}

#pragma mark - UISearchController
- (void)willPresentSearchController:(UISearchController *)searchController 
{
    self.searchController.hidesNavigationBarDuringPresentation = false; // stop from animating
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    self.searchController.searchBar.showsCancelButton = false;
}

- (void)didDismissSearchController:(UISearchController *)searchController{
    filteredPics=_pics;
}

#pragma mark - UISearchResultsUpdating

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {};

VLSearchController

@interface VLSearchController () 
@end

@implementation VLSearchController{
    UISearchBar *_searchBar;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

-(UISearchBar *)searchBar 
{

    if (_searchBar == nil) {
        _searchBar = [[VLSearchBar alloc] initWithFrame:CGRectZero];
    }
    return _searchBar;
}

   -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{
        if ([searchBar.text length] > 0) {
            self.active = true;
        } else {
            self.active = false;
        }
    }
@end

VLSearchBar

@implementation VLSearchBar

-(void)setShowsCancelButton:(BOOL)showsCancelButton {
    // Do nothing...
}

-(void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
    // Do nothing....
}

@end

你的类是否符合 UISearchResultsUpdatingUISearchBarDelegate 协议? - Praveen Gowda I V
是的,我已经将协议<UISearchBarDelegate、UISearchControllerDelegate、UISearchResultsUpdating>添加到我的UIViewController类中。 - user2253546
你能否发布完整的代码(与UISearchController相关)? - Praveen Gowda I V
我已经发布了使用自定义UISearchController(VLSearchController)以及VLSearchController和VLSearchBar代码的UIViewController。 - user2253546
3个回答

1

看起来你正在将搜索栏的代理设置为VLSearchController类的实例。然而,该类不符合UISearchBarDelegate协议。我认为你想要设置_searchBar.delegate = _searchBar,在那里你已经实现了代理方法。

searchBar只能有一个代理,所以决定哪个类来处理文本更改和显示/隐藏取消按钮,并相应地设置代理。你还在viewDidLoad方法中将searchBar代理设置为UIViewController。

一般来说,请确保正确设置所有代理,以确保调用它们的方法。

我认为你还需要将实例变量设置为你的搜索栏子类的实例。


好的。所以我摆脱了将_searchBar的委托设置为VLSearchController。我保留了在UIViewController的viewDidLoad中的委托分配。我选择将委托设置为UIViewController,因为我处理的数据结构特定于该UIViewController。不幸的是,它仍然无法工作。 - user2253546
我不确定你最后一句话的意思是什么… 当我实例化我的VLSearchController时,一个VLSearchBar的实例也会被实例化… 因此,实例变量(VLSearchController)searchController可以通过self.searchController.searchBar访问VLSearchBar子类的实例。 - user2253546
你是否有使用自定义搜索栏类和自定义搜索控制器的原因,如果所有搜索栏代理方法都将在你的UIViewController中实现?如果没有其他原因,你可能想尝试删除这些类,因为它们似乎除了初始化一个与你的视图控制器中样式相同的新搜索栏之外没有任何作用。 - loudmouth
考虑到您的采纳答案涉及确保 searchBar 代理正确设置,我在想是否可以给我的回复投票或接受答案。很高兴它能工作。干杯 :-) - loudmouth
我会接受你的答案,因为它带领我找到了正确的解决方案 :) 感谢你的贡献。 - user2253546

0

我已经找到了解决自己问题的方法。解决方法是将以下委托方法移动:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [searchBar resignFirstResponder];
}

_searchBar.delegate=self 设置在 VLSearchController 的 -(UISearchBar *)searchBar 方法中。

-1

调用委托来将委托连接到搜索栏。如下所示

 @property(nonatomic, assign) id< UISearchControllerDelegate >     _searchController;


  _searchController = [[VLSearchController alloc]             
initWithSearchResultsController:nil];
self.searchController.searchBar.delegate = self; 
self.searchController.delegate = self;


#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {}

 #pragma mark - UISearchController
 - (void)willPresentSearchController:(UISearchController *)searchController;

 #pragma mark - UISearchResultsUpdating
 - (void)updateSearchResultsForSearchController:(UISearchController   
 *)searchController;

希望这能对你有所帮助,如果不行抱歉,但这应该可以解决问题。祝你有美好的一天!=)

我已经通过编程方式添加了搜索栏。因此,在IB中将不存在的搜索栏连接到其委托不会有帮助。在我发布的代码中,我通过编程方式设置了委托。虽然感谢您的尝试 :) - user2253546
嘿,你能给我点赞吗?我需要获得更多的声望。我会进一步研究这个问题,你可能需要添加IB并为其创建一个IB属性。 - Noah Mayo
你仍然可以编辑搜索栏的属性,只需给它一个类名,以便引用,这样它就知道从哪里获取。 - Noah Mayo
但是 UISearchController 在编程上设置取消显示一次搜索栏文本字段被激活,因此我需要在 VLSearchController 中覆盖的取消方法来防止这种情况发生。 为栏创建一个 IB 不会有所帮助。 如果你能给我找到解决方案,我会点赞 :) - user2253546
这可能会起作用:链接 - Noah Mayo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接