5 methods for loading UIView from Xib files and 5 methods for loading uiviewthrough xib files

Source: Internet
Author: User

5 methods for loading UIView from Xib files and 5 methods for loading uiviewthrough xib files

Defining views are the easiest to maintain in different Xib files. Therefore, a convenient process is very important for loading UIView from Xib files.

Over the past few years, I have found that the only way to easily manage the creation and maintenance of views (or any interface element, usually more) isInstantiate UIView from Xib. Creating and designing interfaces in the interface editor is much more intuitive than using code to write interface la S and define layout constants (sizes, colors) or even some bad magic numbers to limit elements.

Now I will introduce the five methods I have used in different situations.

 

1. Simple Method (the original method for loading UIView from Xib)

This method only applies to a view without any other interactive binding. In addition to being easy to understand at the beginner stage of Cocoa, this method has no special advantages.

First, use the [NSBundle loadNibNamed: owner: options] method with only the first parameter.

Just put the following code in the implementation block of your Controller;

// Instantiate the nib content without any reference to it.NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"EPPZPlainView" owner:nil options:nil]; // Find the view among nib contents (not too hard assuming there is only one view in it).UIView *plainView = [nibContents lastObject]; // Some hardcoded layout.CGSize padding = (CGSize){ 22.0, 22.0 };plainView.frame = (CGRect){padding.width, padding.height, plainView.frame.size}; // Add to the view hierarchy (thus retain).[self.view addSubview:plainView];

 

In the Interface editor, you do not need to make any special settings, except for the view that you want to instantiate a single definition in your controller.

You do not need to bind or even specify the File owner class. However, you need to write the layout code in the code;

In the interface editor, you do not need to set anything else, but only need a View with static content.

 

2. Reference Method (more explicit)

This method is more advanced than the previous method. We need to define a specific application to correspond to a View. one of the troubles is that you need to define a view link attribute in your controller class to link it to your view. This is mainly to make this method too specific, or it can be said that the portability is poor

@interface EPPZViewController () // Define an outlet for the custom view.@property (nonatomic, weak) IBOutlet UIView *referencedView;// An action that triggers showing the view.-(IBAction)showReferencedView; @end @implementation EPPZViewController -(IBAction)showReferencedView{    // Instantiate a referenced view (assuming outlet has hooked up in XIB).    [[NSBundle mainBundle] loadNibNamed:@"EPPZReferencedView" owner:self options:nil];     // Controller's outlet has been bound during nib loading, so we can access view trough the outlet.    [self.view addSubview:self.referencedView];} @end

The above Code indicates that you can define a context view (actually a package or a container) in the interface editor ). This is really useful for defining a Layout View with upper and lower associations in the XIB file (more convenient than using code layout ). But you also need to know the settings of the Interface Editor. File's Owner must be set as the controller instance and the referencedView in Outlets must be associated with a View.

You can see that in the figure, the Class attribute of the File's Owner has been set to the Controller Class (EPPZViewController) and the referencedView has been bound to a View you want)

Note: Do not connect the View Controller with the wrap view (equivalent to the view root container) (even if you think this is correct, do not do this ). This is because the Controller view will be re-allocated when the empty view is instantiated.

  

In this way, you can add a UITableViewCell to the xib file, which is also applicable to the UITableViewCell instance method (you do not need to wrap the view). However, this is not within the scope of this discussion.

  

3. Join action (actually adding a code based on the previous step)

Based on the above, you can easily associate the actions sent by objects in the defined view to the Controller. This is very useful, although it is necessary to combine the view with a specified type of controller. Therefore, you only need to define an IBAction in the master controller. The Code is as follows:

@interface EPPZViewController () @property (nonatomic, weak) IBOutlet UIView *referencedView;-(IBAction)showConnectedActionsView;-(IBAction)connectedActionsViewTouchedUp:(UIButton*) button; @end @implementation EPPZViewController -(IBAction)showConnectedActionsView{    // Instantiate a referenced view (assuming outlet has hooked up in XIB).    [[NSBundle mainBundle] loadNibNamed:@"EPPZConnectedActionsView" owner:self options:nil];     // Controller's outlet has been bound during nib loading, so we can access view trough the outlet.    [self.view addSubview:self.referencedView];} -(IBAction)connectedActionsViewTouchedUp:(UIButton*) button{    // Any interaction (I simply remove the custom view here).    [button.superview removeFromSuperview];} @end

 

Then, simply associate a button event with an action you have defined.

 

4. encapsulation implementation (this step begins to write the Controller code)

In this process, the Controller code becomes complex.

When you want to add some new functions, the code in your controller will immediately increase, although you are trying to avoid it. One way to keep the client code concise is to define a subclass of a custom view. Then define the function as an interface and implement it in the subclass.

The first technique is to delete the File's Owner dependency ., Define a class EPPZSubclassedViewOwner. The only purpose of defining this class is to correctly reference the view in the XIB file.

This does not even need to create an independent file for this custom view. It only needs to define the interface in the Controller's header.

@class EPPZSubclassedView;@interface EPPZSubclassedViewOwner : NSObject@property (nonatomic, weak) IBOutlet EPPZSubclassedView *subclassedView;@end @interface EPPZSubclassedView : UIView+(void)presentInViewController:(UIViewController*) viewController;-(IBAction)dismiss;@end

The advantage of doing so is that we can define an interface to inherit UIView and declare the presentInViewController method. If you need different xib files, such as using different interfaces for the iPhone and iPad, you can write the interface here to replace the code filled with a mess in the controller.

In addition, the dismiss method of the view can also be moved here so that it does not do anything in its own controller. In the implementation, I can properly process all the implementation logic. You can see the following code:

@implementation EPPZSubclassedViewOwner@end @implementation EPPZSubclassedView +(void)presentInViewController:(UIViewController*) viewController{    // Instantiating encapsulated here.    EPPZSubclassedViewOwner *owner = [EPPZSubclassedViewOwner new];    [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:owner options:nil];     // Add to the view hierarchy (thus retain).    [viewController.view addSubview:owner.subclassedView];} -(IBAction)dismiss{ [self removeFromSuperview]; } @end

 

In the XIB file, you need to set appropriate class references. As shown above, the Class of the File's Owner is set to EPPZSubclassedViewOwner, and the Class attribute of the View control is set to EPPZSubclassedView

Associate a view with its reference

 

 

 

Like button events associated with actions, they are associated with IBAction of the definition view, for example.

With the above processing method, you can see that the client code is very simple. It is much better to associate attributes with custom views to control them.

@interface EPPZViewController-(IBAction)showSubclassedView;@end @implementation EPPZViewController -(IBAction)showSubclassedView{    // A tiny one-liner that has anything to do with the custom view.    [EPPZSubclassedView presentInViewController:self];} @end

  

This looks like reusable code, but we still need to add some links between the view and the controller.

 

5. encapsulate everything (a scalable and reusable way to load your defined view from the xib file)

We have successfully separated the view from the Controller above, and we continue to perform better operations in this way. To achieve this, we need to define a small proxy protocol <EPPZDecoupledViewDelegate> to define the functions of the controller and ensure that the controller can process messages from the view. Like the common protocol, it only requires two methods: decoupledViewTouchedUp and decoupledViewDidDismiss, as shown below:

@class EPPZDecoupledView;@interface EPPZDecoupledViewOwner : NSObject@property (nonatomic, weak) IBOutlet EPPZDecoupledView *decoupledView;@end @protocol EPPZDecoupledViewDelegate-(void)decoupledViewTouchedUp:(EPPZDecoupledView*) decoupledView;-(void)decoupledViewDidDismiss:(EPPZDecoupledView*) decoupledView;@end @interface EPPZDecoupledView : UIView// Indicate that this view should be presented only controllers those implements the delegate methods.+(void)presentInViewController:(UIViewController<EPPZDecoupledViewDelegate>*) viewController;-(IBAction)viewTouchedUp;-(IBAction)dismiss;@end

  

The implementation requires a reference from delegateViewController to the Controller so that it can forward the action. You need to tell the control to implement the Code, so you need to declare: UIViewController <EPPZDecoupledViewDelegate>.

Others are as follows:

@implementation EPPZDecoupledViewOwner@end @interface EPPZDecoupledView ()@property (nonatomic, weak) UIViewController <EPPZDecoupledViewDelegate> *delegateViewController;@end @implementation EPPZDecoupledView +(void)presentInViewController:(UIViewController<EPPZDecoupledViewDelegate>*) viewController{    // Instantiating encapsulated here.    EPPZDecoupledViewOwner *owner = [EPPZDecoupledViewOwner new];    [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:owner options:nil];     // Pass in a reference of the viewController.    owner.decoupledView.delegateViewController = viewController;     // Add (thus retain).    [viewController.view addSubview:owner.decoupledView];} -(IBAction)viewTouchedUp{    // Forward to delegate.    [self.delegateViewController decoupledViewTouchedUp:self];} -(IBAction)dismiss{    [self removeFromSuperview];     // Forward to delegate.    [self.delegateViewController decoupledViewDidDismiss:self];} @end

  

Now, you can create a completely independent XIB file without worrying about its context. It only instantiates itself and associates the action with itself. It is reusable and can be instantiated from any UIViewController to implement its proxy protocol declared in the header.

 

The action itself will not do much here, and others will be done in the Controller's proxy implementation method. Therefore, it can customize more features through direct, strict, and formal proxy rules.

 

To make him readable and practical, we can move some declarations into the. m file. Therefore, for the view we define, users only need to care about the declaration of the header. For example

@class EPPZDecoupledView;@protocol EPPZDecoupledViewDelegate-(void)decoupledViewTouchedUp:(EPPZDecoupledView*) decoupledView;-(void)decoupledViewDidDismiss:(EPPZDecoupledView*) decoupledView;@end @interface EPPZDecoupledView : UIView+(void)presentInViewController:(UIViewController<EPPZDecoupledViewDelegate>*) viewController;@end

  

 

Therefore, you only need to implement its proxy interface in the controller, so you only need to introduce <EPPZDecoupledViewDelegate>

@interface EPPZViewController () <EPPZDecoupledViewDelegate>-(IBAction)showDecoupledView;@end @implementation EPPZViewController -(IBAction)showDecoupledView{ [EPPZDecoupledView presentInViewController:self]; } -(void)decoupledViewTouchedUp:(EPPZDecoupledView*) decoupledView{ /* Whatever feature. */ } -(void)decoupledViewDidDismiss:(EPPZDecoupledView*) decoupledView{ /* Acknowledge sadly. */ } @end

  

 

 

GOOD. A beautiful UI module is finished ....

 

Source code access to the following address

Https://github.com/eppz/blog.UIView_from_XIB

 

 

Original article: 5 approach to load UIView from Xib

Http://eppz.eu/blog/uiview-from-xib/

 

Please correct me if the translation is inaccurate or incorrect. You can directly access the original address.

Reprinted please indicate the source

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.