AnyObject & Cannot assign to immutable expression of type 'CGFloat'

262 views Asked by At

I have two example functions. Both do exactly the same thing. The difference lies in the type of the variable "objectName".

The first works. I am specific and set the type to UILabel. Obviously I can only use it with UILabel type objects and recreating the function for each type is just ugly.

func _setUILabelTop(objectName: UILabel, location: CGFloat, offset: CGFloat) {
    let originalBottom = objectName.frame.origin.y + objectName.frame.size.height
    objectName.frame.origin.y = location + offset
    objectName.frame.size.height = originalBottom - objectName.frame.origin.y
}

The second doesn't work. AnyObject is used and XCode gives me an error on lines 2 & 3 of the function. It highlights the text objectName.frame with the error: Cannot assign to immutable expression of type 'CGFloat'

func _setObjectTop(objectName: AnyObject, location: CGFloat, offset: CGFloat) {
    let originalBottom = objectName.frame.origin.y + objectName.frame.size.height
    objectName.frame.origin.y = location + offset
    objectName.frame.size.height = originalBottom - objectName.frame.origin.y
}

My questions:

  1. Is there an object type that allows for UILabel, UIButton, MKMapView
  2. Is there a better way of specifying Top, Bottom, Left OR Right properties individually, without having to calculate widths?

Please be gentle, I've only been using XCode & Swift for a couple of days and this is also my first StackOverflow post. =)

1

There are 1 answers

0
Cristik On

It doesn't make sense to set the top position for any object, since not all objects have this property - take for example a NSString. However you can get the behavior you need by using UIView instead of AnyObject, as almost (if not) all UIKit controls derive from this class.

func _setTop(forView view: UIView, location: CGFloat, offset: CGFloat) {
    let originalBottom = view.frame.origin.y + view.frame.size.height
    view.frame.origin.y = location + offset
    view.frame.size.height = originalBottom - view.frame.origin.y
}

Regarding the calculations, you can optimize the originalBottom computation:

let originalBottom = view.frame.maxY