Swift: get UI objects by ID?
Asked Answered
S

3

11

in iOS, is it possible to assign a string ID to UI objects and then retrieve them in the code by that ID?

I am looking for something similar to the Android's findViewById(id)

Subordinary answered 16/6, 2016 at 3:40 Comment(0)
D
14

you can use viewWithTag but tag is type of Int:

let superView = UIView()
let subView = UIView()
subView.tag = 100
superView.addSubview(subView)
let v = superView.viewWithTag(100)

if use xib or storyboard you can bind id like this: enter image description here

use runtime you can bind obj to obj ,but seems not you want :

objc_setAssociatedObject(superView, "key", subView, .OBJC_ASSOCIATION_RETAIN)
let v = objc_getAssociatedObject(superView, "key")

update:

you can use an enum to get the view :

enum UIKey:String {
    case AA = "aa"


    func findView(byKey:String ,fromView:UIView) -> UIView {
        let v :UIView!

        switch self {
            // get view from real tag value
            case .AA: v = fromView.viewWithTag(1)
        }

        return v
    }
}

then use :

let dict = ["aa":123]

dict.forEach { (key,value) in
    let v = UIKey(rawValue: key)?.findView(key, fromView: self.view)
    //set v with your value

}
Daddylonglegs answered 16/6, 2016 at 4:54 Comment(9)
thanks! I just wish it could be possible to specify a string instead!Subordinary
why isn't it possible to retrieve a UI object by Storyboard label or Restoration ID?Subordinary
@DanieleB because the tag is Int type if you want bind obj to obj you can use runtime to do itDaddylonglegs
@DanieleB the best way to get UI from xib or storyboard is use a @IBOutletDaddylonglegs
Yes, I know, but in my particular case I have 11 custom views which I placed on the storyboard and I was thinking to retrieve them with an ID rather than importing them as @IBOutletsSubordinary
Each of them has a special meaningful string code and I was thinking to retrieve them by that code. I might have to match such string code to an int tag then.Subordinary
@DanieleB show more info about the views and the string , see if i can find a better wayDaddylonglegs
I hold a map of 11 keys (e.g. "aa","ab","ya",etc.). Each key holds a numeric value between 0 and 5. Each key should be rendered as UI object. I would like to iterate on all the 11 keys and set the numeric value to the corresponding UI object (which should display such number). For this reason it would have been useful to retrieve the UI object by that key code.Subordinary
@DanieleB i edited the answer ,maybe it can help you .Daddylonglegs
K
0

As you are having several viewControllers in the storyboard you're probably looking for UIStoryboards storyboard.instantiateViewControllerWithIdentifier(identifier: String)

// Basic example
let viewController = yourStoryboard.instantiateViewControllerWithIdentifier("id") as! UIViewController
Kurdistan answered 16/6, 2016 at 5:44 Comment(2)
Actully, I have several custom views in the same view controllerSubordinary
Ah, got you. Anything is possible and you might get away by having your customViews implementing an identifiable protocol for instance. That being said, I believe it makes sense to follow standard patterns and manipulating views in the Storyboards are generally done through IBOutlets. (or you could use tag as suggested above).Kurdistan
D
0

I needed to share one UITableViewCell descendant with a UIButton across multiple UITableViewControllers. So IBOutlet was not an option for me and I needed something similar to Android findByViewId

So I did it in the UITableViewCell descendant when configure it:

for view in self.contentView.subviews {
            if let button = view as? UIButton {
                button.setTitle(item.label, for: .normal) 
            }
        }

If you have more complicated cell layout I think you may use some specific view properties to identify the required subview.

P.S. from my experience using the Tag property for such purposes is generally not a good idea.

Denman answered 7/5, 2018 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.