How to Loop Through View Outlets in a Uiviewcontroller with Swift

How to loop through view outlets in a UIViewController with Swift?

This is what Outlet Collections are for. Drag all your textfields in the same Outlet Collection in InterfaceBuilder and create an @IBOutlet to that collection in your class file:

To create the outlet collection in InterfaceBuilder, ctrl-drag from the first UITextField to your class file in the assistant editor. Then choose Outlet Collection:

Sample Image

ctrl-drag the next UITextField on that @IBOutlet to add it to the collection:

Sample Image

Repeat that for all your textFields.

@IBOutlet var textFields: [UITextField]!

func checkTextFields() {
for textField in self.textFields {
... // do your checks
}
}

How do I access an outlet from another View Controller? (Swift)

Short answer: Don't do that. You should treat a view controller's views as private.

If you mess with another view controller's views you are violating the principle of encapsulation. One module should not depend on the implementation details of another module.

Instead, add a Bool function showTrophy(_ show: Bool).

Keep a pointer to the other view controller (don't create a new instance, as aheze points out.)

In your AccomplishmentsViewController's showTrophy method set the visibility of your trophy icon appropriately.

How to iterate all the UIViewControllers on the app

Access them codewise like this:

NSArray * controllerArray = [[self navigationController] viewControllers];

for (UIViewController *controller in controllerArray){
//Code here.. e.g. print their titles to see the array setup;
NSLog(@"%@",controller.title);
}

How to loop through all UIButtons in my Swift view?

This code should work:

for view in self.view.subviews as [UIView] {
if let btn = view as? UIButton {
btn.setTitleForAllStates("")
}
}

You need to iterate through the subViews array.

How can I loop through all subviews of a UIView, and their subviews and their subviews

Use recursion:

// UIView+HierarchyLogging.h
@interface UIView (ViewHierarchyLogging)
- (void)logViewHierarchy;
@end

// UIView+HierarchyLogging.m
@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy
{
NSLog(@"%@", self);
for (UIView *subview in self.subviews)
{
[subview logViewHierarchy];
}
}
@end

// In your implementation
[myView logViewHierarchy];

Accessing methods, actions and/or outlets from other controllers with swift

Of course you can't create IBAction or IBOutlet for a control in a different ViewController!!
But simply each view controller in the hierarchy has a reference for its child view controllers.

Method 1:

@IBAction func buttonTapped(_ sender: Any) {
let splitViewController = self.childViewControllers[0] as! YourSplitViewController
let targetViewController = splitViewController.childViewControllers[0] as! YourTargetViewController
targetViewController.label.text = "Whatever!"
}

Method 2:

It may be better if you took a reference for each child controller in your "prepare for segue" method

ContainerViewController:

var mySplitViewController: YourSplitViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "splitViewSegue" {
self.mySplitViewController = segue.destination as! YourSplitViewController
}
}

YourSplitViewController:

var aViewController: YourFirstViewController?
var bViewController: YourSecondViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "aViewSegue" {
self.aViewController = segue.destination as! YourFirstViewController
} else if segue.identifier == "bViewSegue" {
self.bViewController = segue.destination as! YourSecondViewController
}
}

So you can access it like that in your container view controller:

@IBAction func buttonTapped(_ sender: Any) {
self.mySplitViewController.firstViewController.label.text = "Whatever!"
}

Connecting Objects with two View controllers in Swift

Short answer: 1. Yes, and yes. 2. There's no better way, and you're not doing something horribly wrong. (You probably just missed a step.)

You have two view controllers. Assuming they are different, you would subclass each one from UIViewController with a different name. E.g., mainSceneViewController and otherSceneViewController.

Your mainSceneViewController and otherSceneViewController would each have their own properties and IBOutlets.

Where you're probably stuck, is needing to change the class of your viewController within Interface Builder to match the class name in its .swift file, so IB knows what outlets it can connect for that view controller.

Each scene in your storyboard corresponds to a view controller. When the segue is performed, iOS instantiates your view controller from the storyboard.

While it is possible to only have one view controller subclass, and use the same subclass for different views, it doesn't happen too often.

Update:

Subclassing lets you add properties and methods to a class, and override their superclass.

In your comment, UIViewController is the class, and mainSceneViewController is subclassed from UIViewController. For your second view controller, it would likely be class otherSceneViewController: UIViewController {, as your other scene would likely require a different properties and methods from your main scene view controller.

You can read more about Inheritance in the Swift Programming Language guide.



Related Topics



Leave a reply



Submit