subViewA 如何改变 subviewB 的参数?
How subViewA change the param on subviewB?
我用
创建了 two views in Main.storyboard
class ViewController: UIViewController
{
var cardsOnTableCounts = 0
@IBOutlet weak var headStackView: HeadStackView!
@IBOutlet weak var gridCardView: GridView!
@objc func touchDeal3Card ()
{
gridCardView.cellCounts += 3
}
}
我在 class HeadStackView
中创建了一个按钮
class HeadStackView: UIView
{
var deal3Card: UIButton = UIButton.init()
override func draw(_ rect: CGRect) {
setDeal3Card()
}
private func setDeal3Card () {
let leftButtonFrame : CGRect = CGRect(x: bounds.maxX/15, y: bounds.maxY/6, width: bounds.maxX/3, height: bounds.maxY*0.7)
deal3Card = UIButton.init(frame: leftButtonFrame)
deal3Card.backgroundColor = UIColor.purple
deal3Card.setTitle("Deal 3 Cards", for: .normal)
deal3Card.addTarget(self, action: #selector(ViewController.touchDeal3Card), for: .touchUpInside)
addSubview(deal3Card)
}
在GridView.swift
class GridView: UIView
{
var cellCount: Int = 5 {didSet { setNeedsDisplay(); setNeedsLayout()}}
override func layoutSubviews() {
super.layoutSubviews()
drawGrid() // it draws cellCount of cells
}
}
我的目标是当 UIButton deal3Card 被按下时,gridCardView 将在 gridCardView 上重新绘制更多卡片。
上面的代码通过了编译器并显示了按钮(deal3card)。但是当我点击按钮时,出现异常:
2018-10-23 19:52:54.283032+0200 gridTest[23636:5175258]
-[gridTest.HeadStackView touchDeal3Card]: unrecognized selector sent to instance 0x7fb97180c8f0
2018-10-23 19:52:54.287469+0200 gridTest[23636:5175258] ***
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[gridTest.HeadStackView
touchDeal3Card]: unrecognized selector sent to instance
0x7fb97180c8f0'
崩溃的最直接原因是这一行:
deal3Card.addTarget(self,
action: #selector(ViewController.touchDeal3Card), for: .touchUpInside)
目标self
错误。您想要将此消息发送到实现 touchDeal3Card
的视图控制器。但是在您的代码中,self
是按钮,而按钮不是。
根据您构建的架构,最简单的解决方案是将 self
替换为 nil
。这将导致 touchDeal3Card
向上渗透响应链并到达视图控制器。
话虽如此,我认为架构本身是错误的。视图控制器应该控制视图;意见不应该控制自己。视图控制器,而不是视图,应该创建按钮。这段代码完全错误的事实很好地表明了这一点:
override func draw(_ rect: CGRect) {
setDeal3Card()
}
这完全是对 draw
的误用,会给您带来可怕的麻烦。在 draw
你唯一应该做的就是(等待)画画。在 draw
中添加子视图是错误的。
我用
创建了 two views in Main.storyboardclass ViewController: UIViewController
{
var cardsOnTableCounts = 0
@IBOutlet weak var headStackView: HeadStackView!
@IBOutlet weak var gridCardView: GridView!
@objc func touchDeal3Card ()
{
gridCardView.cellCounts += 3
}
}
我在 class HeadStackView
中创建了一个按钮class HeadStackView: UIView
{
var deal3Card: UIButton = UIButton.init()
override func draw(_ rect: CGRect) {
setDeal3Card()
}
private func setDeal3Card () {
let leftButtonFrame : CGRect = CGRect(x: bounds.maxX/15, y: bounds.maxY/6, width: bounds.maxX/3, height: bounds.maxY*0.7)
deal3Card = UIButton.init(frame: leftButtonFrame)
deal3Card.backgroundColor = UIColor.purple
deal3Card.setTitle("Deal 3 Cards", for: .normal)
deal3Card.addTarget(self, action: #selector(ViewController.touchDeal3Card), for: .touchUpInside)
addSubview(deal3Card)
}
在GridView.swift
class GridView: UIView
{
var cellCount: Int = 5 {didSet { setNeedsDisplay(); setNeedsLayout()}}
override func layoutSubviews() {
super.layoutSubviews()
drawGrid() // it draws cellCount of cells
}
}
我的目标是当 UIButton deal3Card 被按下时,gridCardView 将在 gridCardView 上重新绘制更多卡片。
上面的代码通过了编译器并显示了按钮(deal3card)。但是当我点击按钮时,出现异常:
2018-10-23 19:52:54.283032+0200 gridTest[23636:5175258] -[gridTest.HeadStackView touchDeal3Card]: unrecognized selector sent to instance 0x7fb97180c8f0
2018-10-23 19:52:54.287469+0200 gridTest[23636:5175258] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[gridTest.HeadStackView touchDeal3Card]: unrecognized selector sent to instance 0x7fb97180c8f0'
崩溃的最直接原因是这一行:
deal3Card.addTarget(self,
action: #selector(ViewController.touchDeal3Card), for: .touchUpInside)
目标self
错误。您想要将此消息发送到实现 touchDeal3Card
的视图控制器。但是在您的代码中,self
是按钮,而按钮不是。
根据您构建的架构,最简单的解决方案是将 self
替换为 nil
。这将导致 touchDeal3Card
向上渗透响应链并到达视图控制器。
话虽如此,我认为架构本身是错误的。视图控制器应该控制视图;意见不应该控制自己。视图控制器,而不是视图,应该创建按钮。这段代码完全错误的事实很好地表明了这一点:
override func draw(_ rect: CGRect) {
setDeal3Card()
}
这完全是对 draw
的误用,会给您带来可怕的麻烦。在 draw
你唯一应该做的就是(等待)画画。在 draw
中添加子视图是错误的。