6

UISearchController它所做的一切是如何做到的?

  • 它如何将其转换UISearchBar为类似导航栏的视图?
  • 它如何将其UISearchBar放入另一个视图层次结构并在以后恢复它?
  • 它是如何使用UIViewController演示 API 完成这一切的?
  • 即使在所有呈现的视图控制器都是全屏的 iPhone 上,它如何只覆盖呈现视图控制器的视图?

我可以在UISearchController不使用私有 API 的情况下自己制作吗?

4

1 回答 1

1

UISearchController创建一个UISearchBar并在其内部_connectSearchBar方法中调用一个私有方法UISearchBar _setSearchController。然后在UISearchBar的内部事件方法中,例如_searchFieldBeginEditing它首先调用它的公共委托方法,然后[__searchController _searchBarTextDidBeginEditing:]允许控制器也处理事件。这就是启用“您可以自由成为UISearchBar的代表”功能的原因。

类似地,在UISearchBar's 文本字段开始编辑它调用UISearchController's _searchBarTextDidBeginEditingwhich 调用_performAutomaticPresentationwhich 使用转换协调器为演示文稿设置动画。

UISearchBar'sdidMoveToSuperView中,它调用[__searchController _searchBarSuperviewChanged]which 首先检查它的 searchBar 是否已放在 a 上UITableView,如果是,它会配置其背景颜色、插图等以供查看。

是的,您可以自己构建这一切,但不能UISearchBar像在 Java 中那样通过子类化,而不是使用可能变得复杂的继承来实现更扁平的类层次结构的 ObjC 的委托模式。例如,您有一个控制器类,它UISearchBar在其 init 方法中采用 a,将自身设置为其委托,然后使用委托转发以允许现有委托方法仍被外部公共委托调用。这是一个除表格视图外的示例:

- (instancetype)initWithTableView:(UITableView *)tableView{
    self = [super init];
    if (self) {
        tableView.delegate = self;
        _tableView = tableView;
    }
    return self;
}

- (id)forwardingTargetForSelector:(SEL)aSelector{
    if(MHFProtocolHasInstanceMethod(@protocol(UITableViewDelegate), aSelector)){
        if([self.tableViewDelgate respondsToSelector:aSelector]){
            return self.tableViewDelgate;
        }
    }
    return [super forwardingTargetForSelector:aSelector];
}

-(void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
    if([self.tableViewDelgate respondsToSelector:_cmd]){
        return [self.tableViewDelgate tableView:tableView didEndEditingRowAtIndexPath:indexPath];
    }
    [self performSelector:@selector(updateSelectionForCurrentVisibleDetailItem) withObject:nil afterDelay:0];
}

这种模式的重点是控制器的子类不再需要调用 super 以确保一切仍按预期工作,而无需程序员调用 super。它还提供了更多可重用的类,因为它可以与任何类型的搜索栏一起使用。

于 2018-10-25T16:33:19.360 回答