在Array中检索/设置UIView对象的值(Retrieving/setting values of UIView Objects in Array)

我在ViewController中有一个名为Keyboard的UIView类来创建可自定义的钢琴键盘图表:

class Key: UIView { var keyType = 0 var keyTypeArray = ["A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab"] // error key type: 0 // white key types: 1, 3, 4, 6, 8, 9, 11 // black key types: 2, 5, 7, 10, 12 init() { super.init(frame: CGRect()) self.backgroundColor = .white self.layer.borderWidth = 1 self.clipsToBounds = false self.layer.shadowOffset = CGSize(width: 5, height: 5) self.layer.shadowOpacity = 1.0 self.layer.shadowRadius = 5 self.layer.shadowColor = UIColor(red: 44.0/255.0, green: 62.0/255.0, blue: 80.0/255.0, alpha: 1.0).cgColor self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner] } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class Keyboard: UIView { let initialKey: Int let numberOfKeys: Int var scale: Double var keys = [Key]() var numWhiteKeys = 0 var numBlackKeys = 0 var startingX: CGFloat = 100.0 var startingY: CGFloat = 200.0 var zPos: CGFloat var keyboardDimensions = [23.0, 24.0, 14.0, 91.0, 52.0] // narrowWhiteKeyWidth = 23.0 // wideWhiteKeyWidth = 24.0 // blackKeyWidth = 14.0 // whiteKeyHeight = 91.0 // blackKeyHeight = 52.0 var blackOffsetsArray = [20.0, 38.0, 14.0, 19.0, 36.0, 13.0, 17.0] var whiteOffsetsArray = [3.0, 9.0, 5.0, 11.0, 7.0] var nextBlackKeyPos = [41.0, 28.0, 41.0, 27.0, 27.0] init(startingX: CGFloat, startingY: CGFloat, initialKey: Int, numberOfKeys: Int, scale: Double, zPos: CGFloat) { self.startingX = startingX self.startingY = startingY self.initialKey = initialKey self.numberOfKeys = numberOfKeys self.scale = scale self.zPos = zPos super.init(frame: CGRect()) } @discardableResult func addKeys() -> [UIView] { for (index, _) in blackOffsetsArray.enumerated() { blackOffsetsArray[index] *= scale } for (index, _) in whiteOffsetsArray.enumerated() { whiteOffsetsArray[index] *= scale } for (index, _) in nextBlackKeyPos.enumerated() { nextBlackKeyPos[index] *= scale } for (index, _) in keyboardDimensions.enumerated() { keyboardDimensions[index] *= scale } var counter = initialKey var whiteKeys = [Key]() var blackKeys = [Key]() var wXPos = CGFloat() var bXPos = CGFloat() let blackOffsetsDict = [1: 0, 3: 1, 4: 2, 6: 3, 8: 4, 9: 5, 11: 6] let whiteOffsetsDict = [2: 0, 5: 1, 7: 2, 10: 3, 12: 4] switch initialKey { case 1, 3, 4, 6, 8, 9, 11: wXPos = startingX if let offsetNum = blackOffsetsDict[initialKey] { bXPos = startingX + CGFloat(blackOffsetsArray[offsetNum]) } case 2, 5, 7, 10, 12: bXPos = startingX if let offsetNum = whiteOffsetsDict[initialKey] { wXPos = startingX + CGFloat(whiteOffsetsArray[offsetNum]) } default: print("Error!") } while counter <= (numberOfKeys + initialKey - 1) { var keyNum = Int() let timesIn = Int(counter/12) let key = Key() key.layer.shadowOffset = CGSize(width: 5*CGFloat(scale), height: 5*CGFloat(scale)) key.layer.shadowRadius = 5*CGFloat(scale) if counter <= 12 { keyNum = counter } else if counter > 12 && (counter % 12) != 0 { keyNum = counter - (12 * (timesIn)) } else { keyNum = counter - (12 * (timesIn - 1)) } switch keyNum { case 1, 3, 4, 6, 8, 9, 11: keys.append(key) whiteKeys.append(key) self.numWhiteKeys += 1 key.backgroundColor = UIColor.white key.layer.cornerRadius = 5*CGFloat(scale) key.layer.borderColor = UIColor.black.cgColor key.layer.zPosition = zPos // print("keyNum is \(keyNum), counter is \(counter)") switch keyNum { case 1, 4, 8, 11: key.frame = CGRect(x: Double(wXPos), y: Double(startingY), width: keyboardDimensions[0], height: keyboardDimensions[3]) switch keyNum { case 1: // print(" A") key.keyType = 1 case 4: // print(" C") key.keyType = 4 case 8: // print(" E") key.keyType = 8 case 11: // print(" G") key.keyType = 11 default: key.keyType = 0 print(" Error!") } case 3, 6, 9: key.frame = CGRect(x: Double(wXPos), y: Double(startingY), width: keyboardDimensions[1], height: keyboardDimensions[3]) switch keyNum { case 3: // print(" B") key.keyType = 3 case 6: // print(" D") key.keyType = 6 case 9: // print(" F") key.keyType = 9 default: key.keyType = 0 print(" Error!") } default: key.keyType = 0 print(" Error!") } wXPos += key.frame.width case 2, 5, 7, 10, 12: self.numBlackKeys += 1 key.layer.zPosition = zPos + 1 key.layer.cornerRadius = 2.5*CGFloat(scale) key.layer.borderColor = UIColor.black.cgColor key.backgroundColor = UIColor.darkGray key.layer.shadowOffset = CGSize(width: 2*CGFloat(scale), height: 2*CGFloat(scale)) key.layer.shadowRadius = 2*CGFloat(scale) key.layer.shadowOpacity = 1.0 // print("keyNum is \(keyNum), counter is \(counter)") key.frame = CGRect(x: Double(bXPos), y: Double(startingY), width: keyboardDimensions[2], height: keyboardDimensions[4]) switch keyNum { case 2: // print(" Bb") key.keyType = 2 bXPos += CGFloat(nextBlackKeyPos[0]) case 5: // print(" Db") key.keyType = 5 bXPos += CGFloat(nextBlackKeyPos[1]) case 7: // print(" Eb") key.keyType = 7 bXPos += CGFloat(nextBlackKeyPos[2]) case 10: // print(" Gb") key.keyType = 10 bXPos += CGFloat(nextBlackKeyPos[3]) case 12: // print(" Ab") key.keyType = 12 bXPos += CGFloat(nextBlackKeyPos[4]) default: key.keyType = 0 print(" Error!") } keys.append(key) blackKeys.append(key) default: key.keyType = 0 print("Key # is \(keyNum). Error!") } counter += 1 } return keys } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }

然后我有一个addKeyboard函数来创建每个键盘并将其添加到keyboards数组中:

var keyboards = [Keyboard]() func addKeyboard(startingX: CGFloat, startingY: CGFloat, initialKey: Int, numberOfKeys: Int, scale: Double, zPos: CGFloat) { let myKeyboard = Keyboard(startingX: startingX, startingY: startingY, initialKey: initialKey, numberOfKeys: numberOfKeys, scale: scale, zPos: zPos) myKeyboard.addKeys() myKeyboard.layer.zPosition = zPos var i = 0 while i < myKeyboard.keys.count { view.addSubview(myKeyboard.keys[i]) i += 1 } keyboards.append(myKeyboard) }

最后,在viewDidLoad中,我可以这样调用addKeyboard:

addKeyboard(startingX: 250, startingY: 30, initialKey: 9, numberOfKeys: 7, scale: 1.0, zPos: 2) addKeyboard(startingX: 150, startingY: 100, initialKey: 4, numberOfKeys: 5, scale: 0.5, zPos: 2)

等(另外5个键盘)

我的问题是当我检索我的键盘阵列并尝试更改任何键盘的值。 该数组返回一串带有(0 0; 0 0)帧的UIView,并且我无法从viewDidLoad中更改任何参数。

这个:

print(keyboards) keyboards[5].scale = 2.0 print(keyboards[5].scale) print(keyboards[5].frame)

产生这个:

[<_TtCC17drawKeyboardTest314ViewController8Keyboard: 0x7f9f9b2002e0; frame = (0 0; 0 0); layer = <CALayer: 0x60400003f4c0>>, <_TtCC17drawKeyboardTest314ViewController8Keyboard: 0x7f9f9b105390; frame = (0 0; 0 0); layer = <CALayer: 0x6000002225c0>>

等等

和print(keyboards[5].scale)产生2.0,但实际大小不会改变(上面的最后2个print()调用的结果)。

2.0 (0.0, 0.0, 0.0, 0.0)

我如何更改内容,以便在将键盘添加到键盘阵列后,我可以获得正确的值并根据需要更改它们(例如,调整大小,移动,突出显示某些键)?

非常感谢。

可靠的人

I have a UIView class called Keyboard in my ViewController to create customizable piano keyboard diagrams:

class Key: UIView { var keyType = 0 var keyTypeArray = ["A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab"] // error key type: 0 // white key types: 1, 3, 4, 6, 8, 9, 11 // black key types: 2, 5, 7, 10, 12 init() { super.init(frame: CGRect()) self.backgroundColor = .white self.layer.borderWidth = 1 self.clipsToBounds = false self.layer.shadowOffset = CGSize(width: 5, height: 5) self.layer.shadowOpacity = 1.0 self.layer.shadowRadius = 5 self.layer.shadowColor = UIColor(red: 44.0/255.0, green: 62.0/255.0, blue: 80.0/255.0, alpha: 1.0).cgColor self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner] } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class Keyboard: UIView { let initialKey: Int let numberOfKeys: Int var scale: Double var keys = [Key]() var numWhiteKeys = 0 var numBlackKeys = 0 var startingX: CGFloat = 100.0 var startingY: CGFloat = 200.0 var zPos: CGFloat var keyboardDimensions = [23.0, 24.0, 14.0, 91.0, 52.0] // narrowWhiteKeyWidth = 23.0 // wideWhiteKeyWidth = 24.0 // blackKeyWidth = 14.0 // whiteKeyHeight = 91.0 // blackKeyHeight = 52.0 var blackOffsetsArray = [20.0, 38.0, 14.0, 19.0, 36.0, 13.0, 17.0] var whiteOffsetsArray = [3.0, 9.0, 5.0, 11.0, 7.0] var nextBlackKeyPos = [41.0, 28.0, 41.0, 27.0, 27.0] init(startingX: CGFloat, startingY: CGFloat, initialKey: Int, numberOfKeys: Int, scale: Double, zPos: CGFloat) { self.startingX = startingX self.startingY = startingY self.initialKey = initialKey self.numberOfKeys = numberOfKeys self.scale = scale self.zPos = zPos super.init(frame: CGRect()) } @discardableResult func addKeys() -> [UIView] { for (index, _) in blackOffsetsArray.enumerated() { blackOffsetsArray[index] *= scale } for (index, _) in whiteOffsetsArray.enumerated() { whiteOffsetsArray[index] *= scale } for (index, _) in nextBlackKeyPos.enumerated() { nextBlackKeyPos[index] *= scale } for (index, _) in keyboardDimensions.enumerated() { keyboardDimensions[index] *= scale } var counter = initialKey var whiteKeys = [Key]() var blackKeys = [Key]() var wXPos = CGFloat() var bXPos = CGFloat() let blackOffsetsDict = [1: 0, 3: 1, 4: 2, 6: 3, 8: 4, 9: 5, 11: 6] let whiteOffsetsDict = [2: 0, 5: 1, 7: 2, 10: 3, 12: 4] switch initialKey { case 1, 3, 4, 6, 8, 9, 11: wXPos = startingX if let offsetNum = blackOffsetsDict[initialKey] { bXPos = startingX + CGFloat(blackOffsetsArray[offsetNum]) } case 2, 5, 7, 10, 12: bXPos = startingX if let offsetNum = whiteOffsetsDict[initialKey] { wXPos = startingX + CGFloat(whiteOffsetsArray[offsetNum]) } default: print("Error!") } while counter <= (numberOfKeys + initialKey - 1) { var keyNum = Int() let timesIn = Int(counter/12) let key = Key() key.layer.shadowOffset = CGSize(width: 5*CGFloat(scale), height: 5*CGFloat(scale)) key.layer.shadowRadius = 5*CGFloat(scale) if counter <= 12 { keyNum = counter } else if counter > 12 && (counter % 12) != 0 { keyNum = counter - (12 * (timesIn)) } else { keyNum = counter - (12 * (timesIn - 1)) } switch keyNum { case 1, 3, 4, 6, 8, 9, 11: keys.append(key) whiteKeys.append(key) self.numWhiteKeys += 1 key.backgroundColor = UIColor.white key.layer.cornerRadius = 5*CGFloat(scale) key.layer.borderColor = UIColor.black.cgColor key.layer.zPosition = zPos // print("keyNum is \(keyNum), counter is \(counter)") switch keyNum { case 1, 4, 8, 11: key.frame = CGRect(x: Double(wXPos), y: Double(startingY), width: keyboardDimensions[0], height: keyboardDimensions[3]) switch keyNum { case 1: // print(" A") key.keyType = 1 case 4: // print(" C") key.keyType = 4 case 8: // print(" E") key.keyType = 8 case 11: // print(" G") key.keyType = 11 default: key.keyType = 0 print(" Error!") } case 3, 6, 9: key.frame = CGRect(x: Double(wXPos), y: Double(startingY), width: keyboardDimensions[1], height: keyboardDimensions[3]) switch keyNum { case 3: // print(" B") key.keyType = 3 case 6: // print(" D") key.keyType = 6 case 9: // print(" F") key.keyType = 9 default: key.keyType = 0 print(" Error!") } default: key.keyType = 0 print(" Error!") } wXPos += key.frame.width case 2, 5, 7, 10, 12: self.numBlackKeys += 1 key.layer.zPosition = zPos + 1 key.layer.cornerRadius = 2.5*CGFloat(scale) key.layer.borderColor = UIColor.black.cgColor key.backgroundColor = UIColor.darkGray key.layer.shadowOffset = CGSize(width: 2*CGFloat(scale), height: 2*CGFloat(scale)) key.layer.shadowRadius = 2*CGFloat(scale) key.layer.shadowOpacity = 1.0 // print("keyNum is \(keyNum), counter is \(counter)") key.frame = CGRect(x: Double(bXPos), y: Double(startingY), width: keyboardDimensions[2], height: keyboardDimensions[4]) switch keyNum { case 2: // print(" Bb") key.keyType = 2 bXPos += CGFloat(nextBlackKeyPos[0]) case 5: // print(" Db") key.keyType = 5 bXPos += CGFloat(nextBlackKeyPos[1]) case 7: // print(" Eb") key.keyType = 7 bXPos += CGFloat(nextBlackKeyPos[2]) case 10: // print(" Gb") key.keyType = 10 bXPos += CGFloat(nextBlackKeyPos[3]) case 12: // print(" Ab") key.keyType = 12 bXPos += CGFloat(nextBlackKeyPos[4]) default: key.keyType = 0 print(" Error!") } keys.append(key) blackKeys.append(key) default: key.keyType = 0 print("Key # is \(keyNum). Error!") } counter += 1 } return keys } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }

And then I have an addKeyboard function that creates each keyboard and adds it to a keyboards array:

var keyboards = [Keyboard]() func addKeyboard(startingX: CGFloat, startingY: CGFloat, initialKey: Int, numberOfKeys: Int, scale: Double, zPos: CGFloat) { let myKeyboard = Keyboard(startingX: startingX, startingY: startingY, initialKey: initialKey, numberOfKeys: numberOfKeys, scale: scale, zPos: zPos) myKeyboard.addKeys() myKeyboard.layer.zPosition = zPos var i = 0 while i < myKeyboard.keys.count { view.addSubview(myKeyboard.keys[i]) i += 1 } keyboards.append(myKeyboard) }

Finally, in viewDidLoad, I can call addKeyboard like so:

addKeyboard(startingX: 250, startingY: 30, initialKey: 9, numberOfKeys: 7, scale: 1.0, zPos: 2) addKeyboard(startingX: 150, startingY: 100, initialKey: 4, numberOfKeys: 5, scale: 0.5, zPos: 2)

etc. (5 more keyboards)

My problem is when I retrieve my keyboards array and try to change any of the keyboards' values. The array returns a bunch of UIViews with frames of (0 0; 0 0), and I can't change any parameters from viewDidLoad.

This:

print(keyboards) keyboards[5].scale = 2.0 print(keyboards[5].scale) print(keyboards[5].frame)

yields this:

[<_TtCC17drawKeyboardTest314ViewController8Keyboard: 0x7f9f9b2002e0; frame = (0 0; 0 0); layer = <CALayer: 0x60400003f4c0>>, <_TtCC17drawKeyboardTest314ViewController8Keyboard: 0x7f9f9b105390; frame = (0 0; 0 0); layer = <CALayer: 0x6000002225c0>>

etc.

and the print(keyboards[5].scale) yields 2.0 but the actual size doesn't change (results of last 2 print() calls above).

2.0 (0.0, 0.0, 0.0, 0.0)

How do I change things so that I after I add my Keyboards to the keyboards array, I can then get the proper values and change them as needed (for example, resize, move around, highlight certain keys)?

Thanks so much.

Jake

最满意答案

情侣问题...

您正在定义一个class Keyboard: UIView ,并在该类中创建(并为其设置框架)一组class Key: UIView 。

但是,您应该将这些Keys添加为ViewController 视图的子视图,而您应该将它们添加为Keyboard视图的子视图。 然后,您可以将keyboard添加到主.view 。 (注意:您还需要设置键盘对象的框架以包含其键)。

当您更改.scale属性时,您的代码无法执行任何.scale 。

一种选择是添加“resize()”类型函数,并直接调用它,或者在更改scale属性时自动调用它。 也许是这样的:

var scale: Double { didSet { self.resize() } }

作为一个方面说明,您可能会得到更好的结果 - 而且我预计从长远来看它会更容易 - 使用自动调整大小和约束,而不是“键”的明确位置和大小。

Couple issues...

You are defining a class Keyboard: UIView, and within that class you are creating (and setting frames for) a bunch of class Key: UIView.

However, you are adding those Keys as subviews of the main view of your ViewController, when you should be adding them as subviews of the Keyboard view. You would then add the keyboard to your main .view. (Note: you'll also need to set the frame of the keyboard object to contain its keys).

Your code is not doing anything when you change the .scale property.

One option is to add a "resize()" type function, and either call that directly, or call it automatically when you change the scale property. Perhaps like so:

var scale: Double { didSet { self.resize() } }

As a side note, you will likely get better results - and I expect it will be easier in the long run - to use auto-sizing and constraints rather than explicit positions and sizes for the "keys".

更多推荐