在Swift中,UISearchBar的value(forKey:)方法有什么作用?

4

在使用Swift中的UITableView和UISearchBar时,我想找到一种方法,在用户搜索后滚动表格视图时保持搜索栏上的取消按钮可用,这样他们就不必点击两次以取消搜索。退出第一响应者(或结束对搜索栏的编辑)的默认行为会使取消按钮变灰,但我想将其保持启用状态。因此,在Stackoverflow上我找到了如何做到这一点的方法,但我无法找到关于下面代码中searchBar.value(forKey: "cancelButton")的解释。显然,它在某种程度上是在创建对搜索栏上的取消按钮的引用,但我不明白.value表示什么(因为我是一个新手),而"cancelButton"键来自何处。我已经阅读了func value(forKey key:String)的文档,但仍然不理解它。如果有人能解释一下这段代码是做什么的就太好了。

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        searchBar.resignFirstResponder()
        // If the user scrolls, keep the cancel button enabled
        if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton {  // <-- This line
            if searchBar.text != "" { cancelButton.isEnabled = true }
            else { searchBar.showsCancelButton = false }
        }
    }

提前致谢。


因为UISearchBar有一个名为cancelButton的“隐藏”属性。顺便说一下,您正在访问一个私有变量,该名称是通过逆向工程找到的。它可能会在下一个iOS版本中被重命名,或者可能会导致您被AppStore拒绝。这三个方法之间有什么区别:valueForKeyobjectForKeyvalueForKeyPath - Larme
你想让取消按钮始终处于启用状态,无论是搜索还是取消搜索吗?是这样吗? - Speedy
3个回答

2

UISearchBarUIView的子类,它继承了UIResponderNSObject。所有的NSObject都符合NSKeyValueCoding Protocol Reference

valueForKey:是一个KVC方法。它适用于任何NSObject类和符合上述协议的其他内容。使用valueForKey:可以使用属性名称的字符串访问属性。例如,如果我有一个带有属性numberAccount类,我可以这样做:

let myAccount = Account(number: 12)
myAccount.value(forKey: "number")

由于它是运行时检查,无法确定返回类型,因此您需要手动进行强制转换,例如:

let number = myAccount.value(forKey: "number") as? Int

这里我不会解释 downcast 和 optionals

因此,您可以仅仅知道方法的确切名称(可以通过简单的反向工程轻松找到)就可以访问符合 NSKeyValueCoding 的任何对象的任何属性。

还有一种类似的方法叫做performSelector,它可以让您执行对象的任何函数

⚠️ 但请注意,如果您触及系统的私有变量或函数,苹果将拒绝您的应用程序。(如果他们发现了!)

⚠️ 还要注意,任何这些都可能被重新命名而不事先通知,从而导致您的应用程序面临未定义的行为。


0
在iOS 12或更早版本的搜索栏中,要访问元素,您可以使用键值来访问这些元素。就像这个函数 -
private func configureSearchBar() {
    searchBar.barTintColor = Color.navBarColor
    searchBar.makeRounded(cornerRadius: 5, borderWidth: 1, borderColor: Color.navBarColor)
    searchBar.placeholder = searchBarPlaceholderText
    searchBar.setImage(Images.search_white, for: .search, state: .highlighted)
    searchBar.setImage(Images.green_check, for: .clear, state: .normal)

    if let textField = searchBar.value(forKey: "searchField") as? UITextField {
        textField.textColor = .white
        
        textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
        
        let leftSideImage = textField.leftView as? UIImageView
        leftSideImage?.tintColor = .white
    }
    
    if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton {
        cancelButton.setTitleColor(.white, for: .normal)
    }
}

通过使用键,我们可以访问搜索栏的元素。


0
我遇到了与您相同的问题,需要搜索列表,但我意识到可以使用UITextfields来实现...
使用didReturn执行textfield.resignFirstResponder(),当它放弃第一响应者时,使用textfield.value获取值以搜索列表。

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