I found a problem whereby the repeated calls to layoutSubviews(), in which I created my subviews (of UIImageView) and attached the necessary animations, caused the animations to constantly repeat without the possibility of stopping them. So, it became necessary to find another way to achieve the creation of the subviews and the attaching of the animations.
The obvious thing to do would be to move the layoutSubviews() code
override func layoutSubviews() {
super.layoutSubviews()
print("layoutSubviews()")
spindleLeft = addSpindle(index: 1, posX: 505, posY: 350)
spindleRight = addSpindle(index: 2, posX: 1610, posY: 350)
spinSpindle(spindle: spindleLeft)
spinSpindle(spindle: spindleRight)
}
to the init
init(cassetteType: CassetteType) {
self.cassetteType = cassetteType
super.init(image: UIImage(named: self.cassetteType.rawValue + "Cassette"))
self.translatesAutoresizingMaskIntoConstraints = false
self.isUserInteractionEnabled = true
self.contentMode = .scaleAspectFit
print("init(cassetteType:)")
spindleLeft = addSpindle(index: 1, posX: 505, posY: 350)
spindleRight = addSpindle(index: 2, posX: 1610, posY: 350)
spinSpindle(spindle: spindleLeft)
spinSpindle(spindle: spindleRight)
}
However, when I do this, the spindle subviews don't show up anymore. They do appear to have been created and the animations are applied but they are no longer visible.
Why would this be the case? How do the layoutSubviews and init differ in this regard?
The addSpindle() code creates each subview like so:
func addSpindle(index: Int, posX: CGFloat, posY: CGFloat) -> UIImageView {
let cassetteBounds = self.bounds
let cassetteWidth = cassetteBounds.width
let cassetteHeight = cassetteBounds.height
let cassetteImageWidth = self.image!.size.width
let cassetteImageHeight = self.image!.size.height
var scale = cassetteWidth / cassetteImageWidth
var spindleWidth = cassetteWidth
var spindleHeight = cassetteImageHeight*scale
var spindleX = 0 as CGFloat
var spindleY = (cassetteHeight - spindleHeight)/2
if spindleHeight > cassetteHeight {
scale = cassetteHeight / cassetteImageHeight
spindleHeight = cassetteHeight
spindleWidth = cassetteImageWidth*scale
spindleY = 0 as CGFloat
spindleX = (cassetteWidth - spindleWidth)/2
}
let spindle = UIImageView(image: UIImage(named: self.cassetteType.rawValue + "Spindle"))
self.addSubview(spindle)
spindle.frame.origin.x = spindleX + (posX*scale)
spindle.frame.origin.y = spindleY + (posY*scale)
spindle.frame.size.width = spindle.image!.size.width*scale //299.0
spindle.frame.size.height = spindle.image!.size.height*scale //299.0
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
gesture.numberOfTouchesRequired = 1
gesture.minimumPressDuration = 0
spindle.isUserInteractionEnabled = true
spindle.isExclusiveTouch = true
spindle.tag = index
spindle.addGestureRecognizer(gesture)
return spindle
}
You're using self.bounds in your addSpindle method. As the view is not laid out yet on init, it's bounds are not determined yet.
You may create your spindle views on init but you need to set their frames on layoutSubviews when the parent's bounds are calculated.