【问题标题】:UISearchBar Cancel ButtonUISearchBar 取消按钮
【发布时间】:2011-12-16 15:50:32
【问题描述】:

在 iOS 5 上使用带有 showCancelButton=YES 的 UISearchBar。希望取消按钮在键盘下拉时保持启用状态。使用以下代码似乎不起作用:

for (id subView in self.searchControl.subviews) {
    if ([subView isKindOfClass:[UIButton class]]) {
        UIButton *cancelButton = (UIButton *)subView;
        [cancelButton setEnabled:YES];
        break;
    }         
}

subView 实际上是一个 UINavigationButton,它似乎不是 UIButton 的子类。我在这里想念什么??????在 Apple 文档中也找不到有关 UINavigationButton 类的任何信息。

【问题讨论】:

  • 到目前为止,没有一个答案能解释您应该如何找到取消按钮。例如,字节的答案只使用 isKindOfClass: UIButton,OP 已经说过它不起作用。由于 UINavigationButton 是一个未记录的类,那么这是否意味着发送到该对象的任何消息都会导致您的应用被拒绝?

标签: uisearchbar


【解决方案1】:

设置您的搜索栏委托,然后输入此代码。

- (void) searchBarSearchButtonClicked:(UISearchBar*) theSearchBar
  {
     [theSearchBar resignFirstResponder];
     [theSearchBar setShowsCancelButton:NO animated:YES];
  }
 - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
  {
     [searchBar setShowsCancelButton:YES animated:YES];
  }
  - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
  {
     [searchBar resignFirstResponder];
     [searchBar setShowsCancelButton:NO animated:YES];
  }

斯威夫特 3.0

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
     searchBar.resignFirstResponder()
     searchBar.setShowsCancelButton(false, animated: true)
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
     searchBar.setShowsCancelButton(true, animated: true)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
     searchBar.resignFirstResponder()
     searchBar.setShowsCancelButton(false, animated: true)
}

【讨论】:

    【解决方案2】:

    Swift 5:Swift 4:

    if let btnCancel = searchBar.value(forKey: "cancelButton") as? UIButton {
        btnCancel.isEnabled = true
    }
    

    【讨论】:

      【解决方案3】:

      只是为了改进 Kurt Spindler 在他的帖子中所说的话。虽然这可能并不优越,但它更包含。我使用 dispatch 做同样的事情。

      -(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
          for (UIView *subview in searchBar.subviews)
          {
              if ([subview isKindOfClass:[UIButton class]])
              {
                  int64_t delayInSeconds = .001;
                  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
                  dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                      UIButton * cancelButton = (UIButton *)subview;
                      [cancelButton setEnabled:YES];
                  });
                  break;
              }
          }
      }
      

      这应该适用于需要帮助保持取消启用的每个人。确保稍后通过单击取消或搜索将其隐藏。

      - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
          [searchBar resignFirstResponder];
          [searchBar setShowsCancelButton:NO animated:YES];
      }
      

      【讨论】:

      • 如果你想异步执行一些事情,只需使用 dispatch_async。您不需要具有“几乎即时延迟值”的 dispatch_after。例如。在这种情况下,dispatch_async(dispatch_get_main_queue(), ^(void){...}); 工作得很好。
      • 根据 Kurt 的回答,我相信 0.001 是必要的。如果不是这样,那么你的方法是完全可以接受的。
      【解决方案4】:

      我必须在我的应用程序中解决同样的问题。尝试在部分延迟后执行上述代码,例如

      [self performSelector:@selector(delayedEnable:) withObject:cancelButton afterDelay:0.001];
      
      - (void)delayedEnable:(UIButton*)button {
          button.enabled = YES;
      }
      

      这很丑陋,但这就是为我工作所需要的。或者,如果您实际上使用 UISearchDisplayController 来显示结果,它还应该为您修复取消按钮的行为(我认为 - 我对这个问题的研究较少)。

      【讨论】:

      • 这就像一个魔术..@Kurt 你能告诉我你从哪里得到这个吗?太棒了..upvoted
      【解决方案5】:

      我在搜索栏取消按钮上方放置了一个自定义取消按钮。

      【讨论】:

        【解决方案6】:

        我知道这是旧的,但我能够解决它,我在 SO 上找不到其他任何东西可以为我解决它,所以这就是有效的方法(在 Swift 3 中):

        键盘隐藏时启用取消按钮。将此添加到 viewDidLoad():

        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
        

        在keyboardNotification(notification:)方法中,响应keyboardDidHide通知:

        func keyboardNotification(notification: NSNotification) {
            if notification.name == Notification.Name.UIKeyboardDidHide {
                self.enableSearchCancelButton()
            }
        }
        

        enableSearchCancelButton 取自其他人的回答 here

        func enableSearchCancelButton() {
            //enable the cancel button
            for view1 in searchBar.subviews {
                for view2 in view1.subviews {
                    if let button = view2 as? UIButton {
                        button.isEnabled = true
                        button.isUserInteractionEnabled = true
                    }
                }
            }
        }
        

        最后,不要忘记将视图控制器作为观察者移除:

        deinit {
            NotificationCenter.default.removeObserver(self)
        }
        

        【讨论】:

          猜你喜欢
          • 2012-01-19
          • 2011-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多