Swift - UIBarButtonItem.customView - 重置为原始状态

Posted

技术标签:

【中文标题】Swift - UIBarButtonItem.customView - 重置为原始状态【英文标题】:Swift - UIBarButtonItem.customView - reset to original state 【发布时间】:2018-06-19 20:25:00 【问题描述】:

我有一个导航栏按钮项,它在数据查询期间添加自定义活动指示器视图。查询完成后,我想将按钮设置回原始状态。这是我当前的代码:

let filterActivityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
filterActivityIndicator.color = .yandasRed
filterMenuNavButton.customView = filterActivityIndicator
filterActivityIndicator.startAnimating()
ProductsFilterData.searchShared.updateFilteredCollectionData(source: "Search")  (done) in
        filterActivityIndicator.stopAnimating()
        self.filterMenuNavButton.setBackgroundImage(#imageLiteral(resourceName: "icons8-slider-30"), for: .normal, barMetrics: .default)

我尝试将自定义背景设置为 nil,但没有任何作用。我试过只是重新设置条形按钮项目的背景图像,它什么都不做。有任何想法吗?谢谢!

编辑: 我试图操作的 UIBarButtonItem 位于右侧,但右侧有两个条形按钮项。 filterMenuNavButton 是我要操作的特定按钮的 IBOutlet。

【问题讨论】:

【参考方案1】:

有时失效是一个问题。看来您需要再次将按钮设置为导航栏。它非常聪明,您首先需要将其设置为 nil 才能产生效果。

这是我尝试过的:

let buttonImage: UIImage = #imageLiteral(resourceName: "icons8-slider-30")

let filterMenuNavButton = UIBarButtonItem(image: buttonImage, style: .plain, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = filterMenuNavButton

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) 
    let filterActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    filterMenuNavButton.customView = filterActivityIndicator
    filterActivityIndicator.startAnimating()
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) 
        filterActivityIndicator.stopAnimating()
        filterMenuNavButton.customView = nil
        filterMenuNavButton.setBackgroundImage(buttonImage, for: .normal, barMetrics: .default)
        self.navigationItem.rightBarButtonItem = nil
        self.navigationItem.rightBarButtonItem = filterMenuNavButton
    

我不确定您的设置是什么,但我采用了一个简单的导航视图控制器并将此代码放入其当前(根)视图控制器的 viewDidLoad 中。

最后一部分可能是您正在寻找的并且您需要:

将自定义视图设置为清除 添加图像或更改其他按钮属性 清除按钮项(设置为零) 将按钮项设置回所需的项

我希望这能解决您的问题。我必须说,当指示器正在进行时创建一个新的按钮项可能更有意义。检查以下内容:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) 
    let preservedButtonItem = self.navigationItem.rightBarButtonItem

    let filterActivityIndicator: UIActivityIndicatorView = 
        let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: activityIndicator)
        return activityIndicator
    ()

    filterActivityIndicator.startAnimating()
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) 
        filterActivityIndicator.stopAnimating()
        self.navigationItem.rightBarButtonItem = preservedButtonItem
    

编辑:多个按钮

对于多个按钮,情况应该非常相似。请尝试使用以下内容:

guard let oldItems = navigationItem.rightBarButtonItems else 
    return


var newItems = oldItems

// Find the index of item so we may ereplace it
guard let index = newItems.index(where:  $0 === filterMenuNavButton ) else 
    return

let activityIndicator: UIActivityIndicatorView = 
    let activity = UIActivityIndicatorView()
    return activity
()
newItems[index] = UIBarButtonItem(customView: activityIndicator)

navigationItem.rightBarButtonItems = newItems
DispatchQueue.main.asyncAfter(deadline: .now()+2.0) 
    self.navigationItem.rightBarButtonItems = oldItems

【讨论】:

感谢 Matic 的回复。在我的原始代码中,filterMenuNavButton 是我要操作的 UIBarButton 的 IBOutlet。我使用插座的原因是有两个右栏按钮项目。如果只有一个,您的代码很可能会正常工作,但在这个特定情况下对我来说不是。我应该更具体一点——我的错。我已更新问题以反映这种疏忽。 @AlexRitter 我不希望它有太大的不同。您有一个属性rightBarButtonItems,您可以在其中替换您的按钮。检查我所做的更新。 像魅力一样工作。谢谢。【参考方案2】:

使用自定义视图作为栏按钮项我没有问题:

fileprivate var underlyingButton: UIButton?

...

let barButton = UIButton(type: .custom)
barButton.addTarget(self, action: #selector(stuffs), for: .touchUpInside)
barButton.setImage(image, for: UIControlState())

let rightItem = UIBarButtonItem(customView: barButton)
self.filterMenuNavButton = rightItem

self.underlyingButton = barButton

然后我可以调用简单的做:

guard let button = underlyingButton else 
    return

button.setImage(someOtherImage, for: UIControlState())

【讨论】:

以上是关于Swift - UIBarButtonItem.customView - 重置为原始状态的主要内容,如果未能解决你的问题,请参考以下文章

Swift入门系列--Swift官方文档(2.2)--中文翻译--About Swift 关于Swift

swift 示例BS swift.swift

swift swift_bug.swift

ios 整理(一)swift和oc的区别

swift swift_extension5.swift

swift swift_optional4.swift