如何检查是不是从 Swift 的 XIB 文件中单击了按钮?
Posted
技术标签:
【中文标题】如何检查是不是从 Swift 的 XIB 文件中单击了按钮?【英文标题】:How to check if button is clicked from XIB file in Swift?如何检查是否从 Swift 的 XIB 文件中单击了按钮? 【发布时间】:2017-11-09 18:11:51 【问题描述】:我遇到以下情况。我使用 XIB 文件创建了一个自定义 UIView
。我连接了一个继承自 UIView
的 VC,并将其添加到 File Owner 属性中。使用@IBOutlet
连接两个按钮并将两个按钮连接到相同的@IBAction
方法,这将切换背景颜色,以获得布尔效果。默认情况下不选择任何按钮。
在我的 ViewController.swift
文件中,它与 Storyboard 中的视图控制器连接,我将其作为子视图添加到我的 UICollectionView
单元格中。
根据我的两个模型类(Messages
和 PermissionMessage
),我确定按钮的文本应该是什么。
我的愿望是给按钮添加功能,所以当点击按钮一时,它会触发功能A,如果选择按钮二,就会触发功能B。
此时我不知道应该在哪里执行此逻辑,以确定应该触发哪个函数。另外因为我可以创建相同BooleanView.xib
的不同实例,所以我不能将函数添加到该XIB
文件的文件所有者类中,对吗?
我试图在UICollectionView
的didSelectItemAt
方法中单击按钮,但我无法访问以编程方式添加的自定义UIView
,称为BooleanView()
。
根据单击的按钮向每个实例按钮添加功能的正确方法和方法是什么?
在我的示例中,我想确定当前实例的选定按钮是Manual
还是GPS
。如果是手动,它会做一些事情,比如在我的控制台中打印一个文本,如果选择了 GPS,我想调用我存储在自定义单独类/处理程序中的 LocationManager 的初始化程序。
这个函数放在UICollectionView
的cellForItemAt
方法里面:
if message is PermissionMessage
let bool = BooleanView()
bool.frame = CGRect(x: 60, y: estimatedFrame.height + 15, width: estimatedFrame.width + 15 + 8, height: bool.frame.height)
let permissionType = (message as! PermissionMessage).getTypeOfPermission()
switch permissionType
case .camera:
print("Case: camera")
bool.leftButton.setTitle("Yes", for: .normal)
bool.rightButton.setTitle("No", for: .normal)
cell.addSubview(bool)
case .location:
print("Case: location")
bool.leftButton.setTitle("Manual", for: .normal)
bool.rightButton.setTitle("GPS", for: .normal)
cell.addSubview(bool)
注意:message
变量是indexPath.row
的选定数组条目。
添加到我BooleanView.xib
的自定义UIView类:
class BooleanView: UIView
@IBOutlet var contentView: UIView!
@IBOutlet weak var leftButton: UIButton!
@IBOutlet weak var rightButton: UIButton!
//MARK: Initialization
override init(frame: CGRect)
super.init(frame: frame)
// Load the nib named 'CardView' into memory, finding it in the main bundle.
Bundle.main.loadNibNamed("BooleanView", owner: self, options: nil)
self.frame = contentView.frame
addSubview(contentView)
// Style the custom view
contentView.backgroundColor = UIColor.clear
leftButton.layer.cornerRadius = (leftButton.frame.height / 2)
rightButton.layer.cornerRadius = (rightButton.frame.height / 2)
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)!
@IBAction func pressedButton(_ sender: UIButton)
if sender.backgroundColor == Constants.BOOL_BUTTON.enabled
return
sender.backgroundColor = Constants.BOOL_BUTTON.enabled
sender.titleLabel?.font = UIFont(name: Constants.FONTS.bold, size: (sender.titleLabel?.font.pointSize)!)
if sender.tag == 0
self.rightButton.backgroundColor = Constants.BOOL_BUTTON.disabled
self.rightButton.titleLabel?.font = UIFont(name: Constants.FONTS.regular, size: (self.rightButton.titleLabel?.font.pointSize)!)
else
self.leftButton.backgroundColor = Constants.BOOL_BUTTON.disabled
self.leftButton.titleLabel?.font = UIFont(name: Constants.FONTS.regular, size: (self.leftButton.titleLabel?.font.pointSize)!)
【问题讨论】:
Swift 3- How to get button in UICollectionViewCell work的可能重复 您需要一个集合视图单元子类来获取视图控制器和布尔视图之间的信息。我会在布尔视图中添加某种状态枚举并将其镜像到单元格中。 你能举个例子吗? @theMikeSwan。我查看了可能重复的帖子,并试图让它与委托协议一起工作,但我认为这在我基于 XIB 文件创建的自定义 UIView 类中不起作用.. @Caspert - 您在问题中发布的代码现在有效吗?也就是说,它正确设置了字体和颜色?您需要一种方法来告诉视图控制器该按钮已被点击? 【参考方案1】:首先,您需要一种方法来传达按下了哪个按钮(如果有的话),enum
将为此工作:
enum BooleanViewState
case none
case left
case right
接下来,您的BooleanView
需要能够将其状态传达给相关方。鉴于您只关心给定布尔视图在特定时刻的状态,最简单的方法是使用计算属性。此外,您当前进入视图以设置按钮标题的方法并不是最佳实践,因此我们还将添加一种替代方法:
class BooleanView: UIView
var boolViewState: BooleanViewState
get
if leftButton.backgroundColor == Constants.BOOL_BUTTON.enabled
return .left
else if rightButton.backgroundColor == Constants.BOOL_BUTTON.enabled
return .right
else
return .none
var buttonTitles = (leftTitle: "", rightTitle: "")
didSet
leftButton.setTitle(buttonTitles.leftTitle, for: .normal)
rightButton.setTitle(buttonTitles.rightTitle, for: .normal)
// The rest of you existing class
您可能需要将didSet
添加到获取标题的两个按钮的插座中。 可能在按钮存在之前设置标题。
接下来,您需要从使用默认的 UICollectionViewCell
切换到可以保存 BooleanView
并来回传递内容的自定义子类:
class BooleanViewCell: UICollectionViewCell
@IBOutlet private var boolView: BooleanView!
var boolViewState: BooleanViewState
get
return boolView.boolViewState
var buttonTitles = (leftTitle: "", rightTitle: "")
didSet
boolView.buttonTitles = buttonTitles
您需要更改 cellForItemAt
方法中的一些代码
if message is PermissionMessage
let permissionType = (message as! PermissionMessage).getTypeOfPermission()
switch permissionType
case .camera:
print("Case: camera")
cell.buttonTitles = (leftTitle: "Yes", rightTitle: "No")
case .location:
print("Case: location")
cell.buttonTitles = (leftTitle: "Manual", rightTitle: "GPS")
最后要做的是从didSelectItemAt
中的单元格中读取boolState
guard let cell = collectionView.cellForItem(at: indexPath) as? BooleanViewCell else return
let theState = cell.boolState
// React to the state as needed
这确实意味着您需要将通用 UIView
添加到情节提要中的原型集合视图单元格,将其类设置为 BooleanView
并将其连接到 BooleanViewCell
中的插座。
尽管我在没有编译器的情况下完成了所有这些工作,但它应该会为您解决所有问题,因此我不能保证我没有拼错或遗漏任何东西。
【讨论】:
以上是关于如何检查是不是从 Swift 的 XIB 文件中单击了按钮?的主要内容,如果未能解决你的问题,请参考以下文章
错误:在 swift 中使用 xib 文件注册自定义 tableView 单元格
将数据从 TableViewController 传递到 XIB 文件而不使用 Segues-Swift 3