Explain the basic methods of changing UIButton internal controls in IOS app development _ios

Source: Internet
Author: User
Tags control label

UIButton internal Default has a Uiimageview, Uilabel control, you can use the following properties to access:

Copy Code code as follows:

@property (Nonatomic,readonly,retain) Uiimageview *imageview;
@property (Nonatomic,readonly,retain) Uilabel *titlelabel;

UIButton can display text entirely because of its internal titlelabel, that is, UIButton settitle:forstate: The string of method settings is displayed on the Titlelabel

UIButton's setimage:forstate: A picture of the method settings is displayed on the internal imageview.

Attention:
1. Set the text or text color of the button, you must use the following method

Copy Code code as follows:

-(void) Settitle: (NSString *) title forstate: (uicontrolstate) state;
-(void) Settitlecolor: (Uicolor *) color forstate: (uicontrolstate) state;

Warnning: You can't just get titlelabel. Set text and text colors, such as the following is the wrong way:
Copy Code code as follows:

Button.titleLabel.text = @ "12323";
Button.titleLabel.textColor = [Uicolor Redcolor];

2. Set the small picture inside the button, you must use the following method

Copy Code code as follows:

-(void) SetImage: (UIImage *) image forstate: (uicontrolstate) state;

Warnning: You can't just get ImageView to set up a picture, like the following is wrong:
Copy Code code as follows:

Button.imageView.image = [UIImage imagenamed:@ "Abc.png"];

Well, after reviewing, we'll go into the subject of this article ~

Change UIButton Internal Controls
when the UIButton is set to the title and image, the equivalent UIButton is composed of a Uibuttonlabel + a uiimageview. But their default format is fixed, that is, the left is a uiimage, the right is a uibuttonlabel. Now if we want UIImage to appear on top of this button, let the Uibuttonlabel appear underneath the button.

We can completely customize a control to implement what is said above, or we can change its inner child controls on a uibutton basis. The second method is used here.

1. First, if you want to change the position of the child control, the first thought might be to get the button and then access its ImageView and Titlelabel properties.

We can first print this button to see the internal structure:

Copy Code code as follows:

NSLog (@ "%@", self.button.subviews);

The result of the print is an empty array! What the hell is going on here?

In fact, the child controls inside the UIButton use lazy loading, which means that if the corresponding child controls are not used, they are not loaded.

Then we re assigning the frame to the two controls so that not only the two controls are loaded, we can also see if you can change the frame of the two controls directly to achieve the purpose of rearranging the two controls.

But if you do this, you will find that the actual display of the button inside does not change, indicating that directly changing the UIButton internal control frame is not able to achieve the purpose of reordering.

Then print the child controls inside the button:

Copy Code code as follows:

NSLog (@ "%@", self.button.subviews);

Will find that subviews this array is now a Uiimageview + a uibuttonlabel, now they have a value (because of the previous use of these two controls, so lazy load).

But careful observation, we will find that the frame of these two controls is clearly the one we just assigned, but why does it not appear according to this frame?

Because the print frame is just what we just set up, and UIButton will recalculate the size according to the contents of its Uiimageview and Uibuttonlabel when it is displayed, so even if we change the frame of the child control, You can't really change the position and size of a child control.

2. The second idea is to inherit UIButton and change it on the basis of the original button.

For example, we create a UIButton subclass Cylbutton, and implement the following method in the Cylbutton implementation file:

Copy Code code as follows:

-(CGRect) Titlerectforcontentrect: (cgrect) contentrect//Control label shows where and size
{
Return CGRectMake (0, ContentRect.size.width, ContentRect.size.width, ContentRect.size.height- ContentRect.size.width);
}

-(CGRect) Imagerectforcontentrect: (cgrect) Contentrect//control image shows where and size
{
Return CGRectMake (0, 0, contentRect.size.width, contentRect.size.width);
}

Contentrect generally represent the bounds.size of UIButton.

We can also set the properties of UIButton's internal controls in the initWithFrame: method
-(Instancetype) initWithFrame: (CGRect) frame
{
if (self = [Super Initwithframe:frame]) {
Self.titleLabel.backgroundColor = [Uicolor Bluecolor];
Self.titleLabel.textAlignment = Nstextalignmentcenter;
Self.imageView.backgroundColor = [Uicolor Yellowcolor];
}
return self;
}


We can see that this method can meet our requirements. But there are drawbacks, too, if some of the things we set up in one of these methods are going to be used in another way, then it's not very convenient.

3. A better approach is to rewrite the Layoutsubviews method because it makes it easy to adjust child controls.

Copy Code code as follows:

-(void) layoutsubviews
{
[Super Layoutsubviews];

CGFloat Imagew = self.bounds.size.width;
CGFloat Imageh = Imagew;
Self.imageView.frame = CGRectMake (0, 0, Imagew, Imageh);

CGFloat Titley = Imageh;
CGFloat Titlew = Imagew;
CGFloat Titleh = Self.bounds.size.height-titley;
Self.titleLabel.frame = CGRectMake (0, Titley, Titlew, Titleh);
}


It may be strange to do this, because just outside of this class we also change the frame of ImageView and Titlelabel, but it has no effect, and the same modification in the Layoutsubviews method, why does it work?

Because we've just been outside modifying the frame of the child control, but when the internal Layoutsubviews method is executed, the frame is reset to the size of the image and title. And now we're going to modify their frame directly in the Layoutsubviews, which is equivalent to overriding the step of setting their frame to the default size, so now it's a success, and because in a method, you can share variables.

Also note that if you inherit from UIButton (such as Cylbutton), then when you have a data model and want to assign values to the child controls in the Cylbutton setter method, you cannot do this directly:

Copy Code code as follows:

Self.imageview = ...
Self.text = ...

Since self (Cylbutton) is inherited from UIButton, either image or title is part of the state, so this is necessary:
Copy Code code as follows:

[Self setimage ...];
[Self settitle ...];

Therefore, it can be directly modified, depending on the status of this attribute. If you are in a separate state, then you cannot modify it directly.

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.