Can't get access to custom UIView property - ios

I have UIView subclass
class GraphView: UIView {
var test = false
}
And when I'm trying to get access to the test property via #IBOutlet, I get exc_bad_access error.
What is my problem?

The reason can be, you are trying to access the property of the #IBOutlet before the view has loaded.#IBOutlet is initialised only when view containing the outlet is loaded.

I just had this issue. It turned out the viewController's view was connected to the IBOutlet, instead of my custom view

Related

How to I create an IBOutlet for a progress bar that is inside a collectionviewcell?

I have a progress bar that is in a collectionviewcell. I want to add a border radius to the progress bar, but whenever I add the progress bar to the view controller, it says "Illegal configuration" and "The progressBar outlet from the ViewController to the UIProgressView is invalid. Outlets cannot be connected to repeating content."
#IBOutlet var progressBar: UIProgressView!
That line of code is what causes the error message.
You should put it inside the UICollectionViewCell and set the outlet with YourCollectionViewCell. Don't forgot to set the CustomClass name for your UICollectionViewCell in storyboard to make it into the effect.
class YourCollectinoViewCell: UICollectionViewCell {
#IBOutlet var progressBar: UIProgressView!
}
Hope it helps!
Answer from Bhavin Kansagara is correct, but also note that you can set corner radius in xib file like shown here Is it possible to set UIView border properties from interface builder?

Remove Scroll View and everything in it from the view

I have a Scroll View which contains a UIImageView and an ActivityIndicator. I would like to programmatically remove the Scroll View from the view, including everything inside it. I have tried doing scrollView.removeFromSuperview() (where scrollView is an IBOutlet to the storyboard Scroll View), but I continue to get unexpectedly found nil while unwrapping an Optional value.
You should check your outlet on storyboard, I think you forgot binding your outlets with your code.
I suppose you marked your UIScrollView with ! as not optional.
Make you outlet optional, it should be like:
#IBOutlet weak var scrollView: UIScrollView?
and call removeFromSuperview() on it, like: self.scrollView?.removeFromSuperview()

Using a subclass of UIViewController subclass with subclass of UIView subclass

I have an MVC architecture of a certain view within my app. Now I want to create a subclass of the View and Controller part. The original UIViewController subclass is loaded with a UIView subclass from storyboard. How can I make my subclass of this UIViewController subclass use my subclass of the UIView subclass code when it loads its view?
EDIT
Here's some more details about what I want to do. I currently have these classes:
ControlView
ControlViewController
which are connected with storyboard. I load an instance of ControlViewController using:
self.storyboard!.instantiateViewControllerWithIdentifier("ControlViewController")! as! ControlViewController
Now what I want to do is subclass ControlView so that I can change some constraints and add a few extra subviews. Let's call this subclass ExpandedControlView. I also want to subclass ControlViewController because I want to add some extra actions from ExpandedControlView to the controller. This can be called ExpandedControlViewController.
Then I want to be able to instantiate ExpandedControlViewController and use ExpandedControlView like ControlViewController would with ControlView.
In storyboard, select the hierarchy view.
Then select your UIViewController's View in the hierarchy on the left, and select that view's class in the identity inspector on the right.
Or if you want to do it in code. Override viewDidLoad on ControlViewController, instantiate your custom view and set your ControlViewController's view property to your custom view.
-(void)loadView{
ControlView *myCustomView = [[ControlView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view = myCustomView;
}
One caveat when doing this is that the layout of any subviews might change from the time loadView is called. So if you have subviews in your custom view, you should also override layoutSubviews in your custom view and set all your view's subviews' frame property again there.
Implement loadView in your view controller subclass and set the view property with instance of your custom view subclass.

Defining custom UIViews in storyboard

I want to show my own custom UIView in storyboard. By far I have done following but my custom view is not showing up.
Dragged and dropped a UIView instance in my screen.
Defined the class for this UIView as my custom class.
Have connected this UIView with an IBOutlet in my view controller.
I even tried with below code in viewWillAppear.
self.myView = [[MyCustomView alloc] initWithFrame:frame];
This works if I create an instance of my custom view and add as a subview to my IBOutlet property for my view. So, below code is working but I want to keep track of only my IBOutlet iVar and do not want to play with another object for changes on my custom view:
self.myExtraView = [[MyCustomView alloc] initWithFrame:frame];
[self.myView addSubview:self.myExtraView];
Any idea how to do this in a better way so that I could have just one reference of my custom view and could change properties on it as per will.
Found the issue. With storyboard we must initialize anything in initWithCode method. I was implementing the regular init method.

How to make IBOutlets out of an array of objects?

I want to make an array with a bunch of UIImageViews I have in Interface Builder. Instead of having 20 or 30
IBOutlet UIImageView *img1;
and linking them all that way, and then putting them into an array, is there a way to declare an array of IBOutlet UIImageViews?
Just so I don't have so many declarations in my header file.
It is possible, it’s called outlet collection. This is the way to define an outlet collection:
#property(retain) IBOutletCollection(UIImageView) NSArray *images;
Now you can stick more than one object into the outlet in the Interface Builder, the array will be created for you when the interface is loaded.
I'm a little late here but it may be easier to set the tag property of each ImageView in IB, then access them like [some_superview viewWithTag:tag] rather than keep a separate handle to each one.
Here is more easier way to do it.
Follow these steps to create an array of outlets an connect it with IB Elements:
Create an array of IBOutlets
Add multiple UIElements (Views) in your Storyboard ViewController interface
Select ViewController (In storyboard) and open connection inspector
There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
Connect if with your interface elements
-
class ViewController2: UIViewController {
#IBOutlet var collection:[UIView]!
override func viewDidLoad() {
super.viewDidLoad()
}
}
Swift 3 and above:
#IBOutlet var stuckLabels: [UIImageView]
There's not, unfortunately, but you can keep all of the declarations on a single line:
IBOutlet UIImageView *img1, *img2, *img3, *img4;
The other option (probably best, since you have so many of these) would be to create them programatically and store them in an array, then add them to the view from your view controller class, using, for each,
[self.view addSubview:img];
Also, keep in mind that if the elements are static (like background elements), and you don't actually need to access them, you don't need to declare outlets for each; you can just add them to the nib file and forget about them.
Same goes for UIButton instances. If you don't need to change anything about the button, you can access it from the method that it calls, like so:
-(IBAction) buttonPressed:(id)sender {
UIButton *button = (UIButton *)sender;
// method guts
// stuff with button -- access tag, disable, etc
}

Resources