Kunal Kumar
Kunal Kumar

Reputation: 1722

How to get all the textfields from a view in swift

I have a view which has more than 15 UITextFields. I have to set bottomBorder(extension) for all the UITextFields. I can set it one by one for all the UITextFields and its working too. I want to set the bottom border for all the UITextFields at once. Here is the code I am trying but it seems like that for loop is not executing. I have even tried it in viewDidLayoutSubViews but for loop not executing there too.

 override func viewDidLoad() 
{
    super.viewDidLoad()

    /** setting bottom border of textfield**/

    for case let textField as UITextField in self.view.subviews {
        textField.setBottomBorder()
    }
}

Upvotes: 12

Views: 9549

Answers (8)

Gurjit Singh
Gurjit Singh

Reputation: 1913

Swift: This function will return all text-fields in a view. No matter if field exists in any subview. ;-)

func getAllTextFields(fromView view: UIView)-> [UITextField] {
    return view.subviews.flatMap { (view) -> [UITextField] in
        if view is UITextField {
            return [(view as! UITextField)]
        } else {
            return getAllTextFields(fromView: view)
        }
    }.flatMap({$0})
}

Usage:

getAllTextFields(fromView : self.view).forEach{($0.text = "Hey dude!")}

Generic Way:

func getAllSubviews<T: UIView>(fromView view: UIView)-> [T] {
    return view.subviews.map { (view) -> [T] in
        if let view = view as? T {
            return [view]
        } else {
            return getAllSubviews(fromView: view)
        }
    }.flatMap({$0})
}

Usage:

 let textFields: [UITextField] = getAllSubviews(fromView: self.view)

Upvotes: 18

Shakeel Ahmed
Shakeel Ahmed

Reputation: 6013

Swift 5
A Very simple answer you can understand easyly : - You can handle all kind of Objects like UILable, UITextfields, UIButtons, UIView, UIImages . any kind of objecs etc.

for subviews in self.view.subviews {
    if subviews is UITextField
    {
        //MARK: - if the sub view is UITextField you can handle here
        funtextfieldsetting(textfield: subviews as! UITextField)
    }
    if subviews is UIButton
    {
        //MARK: - if the sub view is UIButton you can handle here
        funbuttonsetting(button: subviews as! UIButton)
    }
    if subviews is UILabel
    {
        //MARK: - if the sub view is UILabel you can handle here
        //Any thing you can do it with label or textfield etc
           
     }
 }

Upvotes: 0

Chen Jiling
Chen Jiling

Reputation: 527

extension:

extension UIView {
    func viewOfType<T:UIView>(type:T.Type, process: (_ view:T) -> Void)
    {        
        if let view = self as? T
        {
            process(view)
        }
        else {
            for subView in subviews
            {
                subView.viewOfType(type:type, process:process)
            }
        }
    }
}

Usage:

view.viewOfType(type:UITextField.self) {
        view in

        view.text = "123"
}

Upvotes: 3

Jamal alaayq
Jamal alaayq

Reputation: 146

func getTextFields() {
    for textField in view.subviews where view is UITextField {
       (textField as? UITextField).setBottomBorder()
    }
}

Upvotes: 1

GBaeOne
GBaeOne

Reputation: 46

This worked for me.

var textFieldsArray = [UITextField]()

for view in self.view.subviews {
    if view is UITextField {
        textFieldsArray.append(view as! UITextField)
    }
}

textFieldsArray.forEach { $0.setBottomBorder() }

If you want to get the result of the function applied in a new array, use map() instead.

Upvotes: 1

Kunal Kumar
Kunal Kumar

Reputation: 1722

I made it working, but still need the explanation why the code in question is not working
I got it from somewhere on the forum, not exactle able to credit the answer.

/** extract all the textfield from view **/
func getTextfield(view: UIView) -> [UITextField] {
var results = [UITextField]()
for subview in view.subviews as [UIView] {
    if let textField = subview as? UITextField {
        results += [textField]
    } else {
        results += getTextfield(view: subview)
    }
}
return results  

Call the above function in viewDidLoad or viewDidLayoutSubviews.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

/** setting bottom border to the textfield **/
    let allTextField = getTextfield(view: self.view)
    for txtField in allTextField
    {
        txtField.setBottomBorder()
    }
}

Upvotes: 10

Kevin Sabbe
Kevin Sabbe

Reputation: 1452

Try this :)

for view in self.view.subviews as! [UIView] {
    if let textField = view as? UITextField {
        textField.setBottomBorder()
    }
}

Upvotes: 1

Anbu.Karthik
Anbu.Karthik

Reputation: 82759

try this

for aSubView: Any in self.view.subviews {
if (aSubView is UITextField) {
    var textField = (aSubView as! UITextField)
    textField. setBottomBorder()
}
}     

or try this

for view in self.view.subviews {
if (view is UITextField) {
     var textField = view as! UITextField
      textField. setBottomBorder()
}
}

Upvotes: 2

Related Questions