Accessing class functions - objective-c

I have created a UIView class. In this class it has touchesbegan and touches moved functions etc. When I create an instance of this class in my UIView controller they don't work.
Is it not possible for the instance to access these functions? I know the class works because if I drag a UIView onto the View Controller and assign it with the class I can drag it and resize it etc.

I have created a UIView class. In this class it has touchesbegan and
touches moved functions etc. When I create an instance of this class
in my UIView controller they don't work.
Check the userInteractionEnabled property of the view. The default value for any UIView is YES, so your view should track touches, but you may have disabled the view in your storyboard or .xib file.
Is it not possible for the instance to access these functions?
It's possible, and the entire touch handling mechanism relies on it. If your view is enabled, and it's not covered up by some other view, and there aren't any gesture recognizers that are stealing its touch events, it should be receiving touch messages.

Related

What's the advantage of using UIViewController as owner of xib?

Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

ios UIview in views

I have a uiview that has all my buttons, that has its controller. How can I include the button view in all my uiviews using the interface builder? The buttons must work when click. The purpose is to increase maintainability.
You can create a custom UIView in interface builder like this:
Loading custom UIView from nib, all subviews contained in nib are nil?
Then add your custom view to other views in IB by adding a normal UIView and changing the class to your subclass.
Try this. I'm not sure that adding UIView in Interface Builder will work, but adding subview programmatically always works.

How do I set a property on a custom view instantiated from a XIB

I am just trying to get my head around MVC in Objective C and IOS but am having a problem I'm hoping someone can help me with.
I have created a custom view (created as a child UIView in a XIB) that uses a simple delegate protocol for requesting information from its delegate in drawRect. I have a view Controller that implementes the protocol and is connected to the view through interface builder.
The custom view also has a few properties that I want to set on startup.
The problem I have is working out how the controller is supposed to access the view to set these properties as it doesn't appear to have direct access to it. Also the properties don't seem to be visible in interface builder inspector as I would expect unlike the delegate property I added.
Initially I thought I could do something like
[self.view setViewIntProperty:10]
But that would be calling the main XIB view and my custom view is actually a child of this view so I need someway to get that specific child view to I can initialise it from the controller in viewDidLoad.
Hopefully that is clear. I'm sure this should be easy and I've missed something simple but can't see how this should normally work.
You can just create another property on your view controller of type MyCustomView*.
Declare that property as an IBOutlet and you wire that up in IB.
Then in your view controller you can use that property to access that custom view.
Your custom view's properties (as opposed to its outlets) can only be set in code unless you create an IB plugin for it.
Your other subviews can be accessed easily if you create an outlet for each of them in your controller. The view outlet is there as the primary view of that view controller. There is nothing preventing you creating additional outlets to other views/controls. Yu would just need to subclass the view controller and add the outlets as needed. Just remember to set the class name of the controller (in Interface Builder) to that of your custom subclass. That will expose the available outlets for you to connect.
You'd still need to create an Interface Builder plugin if you want to make your control's custom properties available in IB's inspector palette. Unless you plan to reuse it frequently in other applications or make it available to others, it's probably easiest just to set the properties in your source code.
Example for setting corner radius of your custom subview (subclass of UIButton in my case) from xib.
Create a property like this
#property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
Override setter in your custom view's implementation file.
-(void)setCornerRadius:(CGFloat)cornerRadius
{
self.layer.cornerRadius = cornerRadius;
}
Drag your view in xib and change its class to your custom class.
Magic... You will see the custom properties appearing in attribute inspector like this.

Handling touch event logic in Subview or ViewController

I have a series of UIView subclasses that are added as subviews. Each subview can be dragged and dropped. When they are dropped (touchesEnded), I need to run a method in the viewController to do some work. I currently have the touchEvents handled in each subview class. Should I be handling these touch events in the viewController or should I be passing a pointer to the parent viewController as a property of each class I have added as subviews?
UPDATE: Or is this a job for NotificationCenter?
UIViewController is a subclass of UIResponder, and instances are automatically inserted in the responder chain behind the views they control. As a result, you can implement the same event methods in subclasses of UIViewController as in subclasses of UIView, and they will 'just work'; that is, they'll be called automatically.
So if your view controller needs to respond to -touchesEnded:withEvent:, just implement the method directly in your UIViewController subclass. If the view also needs to do something in response to the event, you can always send it a message from within your -touchesEnded:withEvent: (or whatever) implementation.
You might try delegating your desired touch handling event from your uiview subclass to the uiviewcontroller using a delegate protocol. The view controller can set itself as delegate as it instantiates or adds each subview.
In MVC paradigm, if you want to handle a touch that's specific to a V view's internals (button appearance/location), then you might want to handle that touch in the V view, but if the touch effects some state outside the view (it's position in a bigger window, etc.) you might want to pass handling that touch up to the C controller to set state in the M model.

The relationship between UIViewController and UIView

I'm trying to understand how these two are connected. Every time you make a UIViewController does it also automatically come with its own UIView?
Also are these from Cocoa or Objective-C?
UIViewController is a Cocoa Touch class built for the purpose of managing UIViews. It expects to have a view hierarchy, but you don't "automatically" get a view (this is slightly inaccurate; see edit below). Usually you will obtain views by calling initWithNibName on your view controller.
There is some built-in magic in Interface Builder which knows that if File's Owner is a UIViewController (or subclass), there is a property called view. That's about it.
Once you have linked a view controller and a view, the view controller does a fair amount of work for you: it registers as a responder for view touch events, registers for device rotation notifications (and handles them automatically, if you wish), helps you take care of some of the details of animation, and handles low-memory conditions semi-automatically.
Edit: correction—if you don't call initWithNibName or set the view property manually, the view property getter will invoke loadView if view is nil. The default implementation of loadView will see if you've set nibBundle and nibName and attempt to load the view from there (which is why you don't have to call initWithNibName, most of the time), but if those properties aren't set, it will instantiate a UIView object with default values. So technically, yes, it does automatically come with its own UIView, but most of the time that's of little value.
UIViewController doesn't automatically come with a view. You have to make a view in the -loadView method. By default, this loads the view from the nib file you've specified. You can also override this method to make a custom view if you prefer not to use a nib.
Also, the view is not created right when the UIViewController is created. UIViewController uses a technique known as lazy-loading to defer the creation of a view until the view is actually accessed for the first time.