Label Text in Objective-C - ios

I have problem about Label.Test
CGRect frame = _gobutton.frame;
frame.origin.x=rand()%330+1;
frame.origin.y=rand()%550+1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
_gobutton.frame = frame;
[UIView commitAnimations];
i=i+1;
self.score.Text = [NSString stringWithFormat:#"%i",i];
I'm trying to move the button around the screen and when I click the button show the score in the label. Currently, when I click the button the score increases but my button moves back to its original locations.
How do I fix this?

The code you posted should animate your button to a new location. As holex says in his comment, you should really be using the newer methods like animateWithDuration:animations: and its variants.
If you are using auto-layout (the default or XIB files and storyboards in Xcode 5 and later) then you can't animate a view (or, which is a type of view) by moving it's frame. Instead you need to use position constraints, attach outlets to the constraints, and change the constraint's constant values.
If you want to animate the frame, you need to turn off auto-layout on your XIB/Storyboard and use the older struts and springs style resizing.

Since you are using the storyboard with auto-layout it will always return to its position.
If you plan on animating a view I would create it programmatically.
_gobutton = [[UIButton alloc] initWithFrame:CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight)];
[_gobutton addTarget:self action:#selector(yourButtonSelector:) forControlEvents:UIControlEventTouchUpInside];
[_gobutton setBackgroundImage:[UIImage imageNamed:#"aphoto"] forState:UIControlStateNormal];
[self.view addSubview:_gobutton];
Just take the button off of the storyboard and create your button like that. You will be able to move it anywhere you want. Its easier then changing the storyboard constraints programmatically.

Related

How to Remove and Adding Constraints when we change simulator orientation(like portrait to landscape) in ios

Hi i am very new for Auto-layouts and in my project i have added Two UIViews programmatically using Auto-layouts and i have added two UIButton which are Next and Back button and when i click Next button i push MyFirst UIView to second UIView using UIView animations and when i click Back button i push back from Second UIView to First UIView ok Everything is all right based on my code
But here my main problem is when i change First UIView orientation in simulator at portrait to landscape then Second UIView overlapped on my First UIView, And i know that it is must be Constrains issue i mean i have to remove and adding Constraints each time when we change Orientation for this i have tried below code but that's not working please help me and for this i have tried since long time but no one saying right answers using constrains
when we run program at portrait mode screen is coming like image1 and when i change land scape mode second UIview overlapped on my first UIview like below second image that's my main problem
my code:-
#import "SubViewController.h"
#interface SubViewController (){
UIButton * GoNext;
UIButton * GoBack;
NSArray * FHorizental;
NSArray * FVertical;
NSArray * SHorizental;
NSArray * SVertical;
}
#end
#implementation SubViewController
#synthesize MyFisrtView,MySecondView;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"How are you");
[self callAutolayouts];
MyFisrtView.hidden = NO;
MySecondView.hidden = YES;
}
-(void)callAutolayouts{
NSLog(#"Hi");
MyFisrtView = [[UIView alloc] init];
MyFisrtView.backgroundColor = [UIColor orangeColor];
MyFisrtView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:MyFisrtView];
MySecondView = [[UIView alloc] init];
MySecondView.backgroundColor = [UIColor lightGrayColor];
MySecondView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:MySecondView];
//Applying autolayouts for MyFirstView and MySecondView
NSDictionary * HeaderDictionary = NSDictionaryOfVariableBindings(MyFisrtView,MySecondView);
//Appliying Autolayouts for FirstView
FHorizental =[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-0-[MyFisrtView]-0-|"]
options:0
metrics:nil
views:HeaderDictionary];
FVertical = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"V:|-0-[MyFisrtView]-0-|"]
options:0
metrics:nil
views:HeaderDictionary];
[self.view addConstraints:FHorizental];
[self.view addConstraints:FVertical];
//Appliying Autolayouts for SEcondView
SHorizental =[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-0-[MySecondView]-0-|"]
options:0
metrics:nil
views:HeaderDictionary];
SVertical = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"V:|-0-[MySecondView]-0-|"]
options:0
metrics:nil
views:HeaderDictionary];
[self.view addConstraints:SHorizental];
[self.view addConstraints:SVertical];
GoNext = [UIButton buttonWithType: UIButtonTypeRoundedRect];
GoNext.frame = CGRectMake(50, 50, 100, 18);
[GoNext setTitle:#"Next" forState:UIControlStateNormal];
[GoNext addTarget:self action:#selector(GoNext:) forControlEvents:UIControlEventTouchUpInside];
GoNext.backgroundColor = [UIColor lightGrayColor];
[MyFisrtView addSubview:GoNext];
GoBack = [UIButton buttonWithType: UIButtonTypeRoundedRect];
GoBack.frame = CGRectMake(50, 50, 100, 18);
[GoBack setTitle:#"Back" forState:UIControlStateNormal];
[GoBack addTarget:self action:#selector(GoBack:) forControlEvents:UIControlEventTouchUpInside];
GoBack.backgroundColor = [UIColor orangeColor];
[MySecondView addSubview:GoBack];
}
-(void)GoNext:(id)sender{
MySecondView.hidden = NO;
MySecondView.frame=CGRectMake(248, 0, self.view.frame.size.width, self.view.frame.size.height); // starting visible position
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[self.view removeConstraints:self.view.constraints];
[self callAutolayouts];
[self.view setNeedsLayout];
[MySecondView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; // final visible position
}
completion:nil];
}
-(void)GoBack:(id)sender{
MySecondView.frame=CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); // starting visible position
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[self.view removeConstraints:self.view.constraints];
[self callAutolayouts];
[self.view setNeedsLayout];
[MySecondView setFrame:CGRectMake(MyFisrtView.frame.size.width, 0, self.view.frame.size.width, self.view.frame.size.height)]; // final visible position
}
completion:nil];
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait){
NSLog(#"portrait");
[self.view removeConstraints:self.view.constraints];
[self callAutolayouts];
[self.view setNeedsLayout];
}
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"LandscapeRight");
[self.view removeConstraints:self.view.constraints];
[self callAutolayouts];
[self.view setNeedsLayout];
}
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
NSLog(#"LandscapeLeft");
[self.view removeConstraints:self.view.constraints];
[self callAutolayouts];
[self.view setNeedsLayout];
}
}
#end
image1:-
image2:-
First you have to remove the constraints and then add agin as you did in your question.
You could follow a tutorial on auto layout so that you can get a little know how about it. Here's a link.
Another option is the use of springs and struts.
I hope that answers your question.
Based on your comments below I'm updating my answer but leaving the original below as it may help you or others down the road.
Your issue isn't really Auto Layout then, your real issue is an architecture design issue. Every view that comes onto screen should have a different view controller running it. It sounds like you are drawing one view that is double the width of the device, one half (I'm guessing the left half) has the next button on it while the other half includes the back button. As soon as your app runs on a screen with a different size this will break unless you are checking for the screen size. Even then it breaks (as you have seen) when the device is rotated.
You need to make two different view controller subclasses, one to run the 'Next' view and one for the 'Back' view then you will never have the both views onscreen because the device got rotated.
The really hard way to get the effect you want is to do it all in code like you've tried thus far. If there is some strange reason that you just have to code it all instead of using the storyboard that was included when you started the project you will need to look at the animation methods of UIView (specifically look at the documentation for + (void)transitionFromView: toView: duration: options: completion: if you want something like a flip or page curl). If you want to slide between the two views you should really look into UINavigationController as it does all that for you. The other option would be when the Next button gets pressed create the second view controller, who will create the second view, and set it's frame to be off screen. Then animate the frame of the view to the onscreen position. Back would have to animate the frame of the Back view off the screen again and remove the view. It will take a lot of code to get all of this working which will mean reading a lot of documentation, I highly recommend using a storyboard to take care of this issue.
If you want the easy way use the storyboard and drag out a second view controller. Add a button to each scene in whatever location you want them to be in and set the text as desired. Control drag from the Next button to the second scene and select the kind of transition you would like. Add the following code to the view controller running the view with the Next button
#IBAction func exitToViewController (sender: UIStoryboardSegue){ }
Control drag from the Back button to the Exit icon (top of the scene all the way to the right, it's red with a white box and an arrow point to the right) select exitToViewController. Select one of the scenes and select Editor -> Resolve Auto Layout Issues -> Reset To Suggested Constraints (the second one under all views). It takes five minutes to do and works wonderfully.
If you need help with any of the tasks mentioned in the Storyboard route consider finding a beginner level tutorial on Xcode (there is a pretty good overview class on Coursera.org that isn't terribly long but covers many of the basics called,Foundations of Objective-C App Development and it's free if you don't care about a verified certificate.
Original Answer
Is there a reason the UI has to be built programmatically?
Building it in IB will make your life much easier as you can build the base version of the UI and then create overrides for specific size classes (look at the bottom of IB where it says w Any h Any and change the selection to be compact height). Once in the compact height make any modifications you need to the constraints and visibility of UI elements. The system should take care of things from there (you might have to manually hide and show the correct UI elements as need for the orientations).
When building in IB one of the Assistant editors is preview. You can select various devices and change the orientation between landscape and portrait, this will allow you to see in real time what your view is going to do when run for real rather than making a change in code and then running the app again. You can add one of each device if you want and they can all have their own orientation allowing you to see the UI in landscape and portrait at the same time.
If it does has to be done in code and you have to actually remove the unused elements from the UI rather than hiding them you will have to set all the constraints for the landscape orientation every time the device rotates to that orientation, the same is true for the portrait orientation. The best thing to do is to make the constraint changes in an animation block rather than manually updating the frames, this will cause the views to animate into place (you can do any alpha adjustments at the same time to fade elements in and out).

Moving UIView from One Tab to another

I'm making this type of screen.
I've used 3 UIButton and programmatically gave them border. The little red line is a UIView. I've provided a constraint to UIView Equal Widths as Trending Button.
Now my question that when user taps the next button this UIView should move to the next one. View Controller is 600x600 and next button is at 200x0 so if I change the value of UIView to 200 that will be hard coded and it'll alter according to the screen size. I want it to be perfect and don't know any other way.UPDATE:I'm using AutoLayout so for this purpose I used [self.buttonBottomView setTranslatesAutoresizingMaskIntoConstraints:YES]; and when I run the app the buttons were messed up like in the screenshot. I've applied some constraints on buttons.
You can use NSLayoutConstraint ,change it's LeadingConstaint when you tap on the next button.
Code:
- (void)changeSelectedByTapView:(UIView *)tapView {
_currentSelectedView = tapView;
self.lineImageViewLeadingConstaint.constant = tapView.frameX;
self.lineImageViewWidthConstaint.constant = tapView.width;
[UIView animateWithDuration:0.5f animations:^{
[self.lineImageView.superview layoutIfNeeded];
}];
}
change frame of your UIView.
view.frame = CGRectMake(0+buttonWidth*i, y, width, height);
i is index which is 0 for Trending, 1 for Made by the fans and 2 for your rules.
Also when you change frame for your view, it is shown only on one button at a time.

UIButton center position doesn't update with rotation

I have a program that dynamically generates UIButtons in the center of
the screen with push of another button.
The buttons are not updating the x-coordinates when I rotate the device.
Here is my code for creating buttons:
- (IBAction)createButton:(UIButton *)sender {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundColor:[UIColor redColor]];
[button addTarget:self action:#selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(self.xCoord,self.yOffset,100.0,120.0);
[self.view addSubview:button];
_yOffset = _yOffset+130;
}
The XCoord and self.yOffset were set in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.yOffset = 109;
self.xCoord = self.view.bounds.size.width/2-50;
}
The coordinates of the button in your code are fixed once they've been added to the view. If you want to update the frame of the buttons when the screen rotates, you'll need to trigger the repositioning of the buttons when the screen rotates.
AutoLayout in a storyboard makes this easier (if you just want a button to appear then you can add it in a storyboard and change its hidden property from NO to YES when the other button is pressed -- this won't be helpful if you want to add an arbitrary number of buttons, although you could have a hidden placeholder view that you use as a positioning reference)
If you want to keep the buttons x-position, you need to add Auto Layout constraints. There are a couple ways to do this programmatically. You can use the NSLayoutConstraint object directly or use Auto Layout's Visual Format Language. For more info, see Apple's documentation.

I want my label disappear on the left and appear on the right on swipe

I have a view with
UIScrollView -> image view
UILabel
I add a swipe gesture on my ScrollView to go to the next image. It works.
My label is the title of my image.
When i swipe, i want my label disappear on the left and appear on the right and set the new title.
Do I need 2 different labels?
How can I animate my label?
Make your label the subview of your scrollView. Then it will scroll when your image does.
You could use
[UIView animateWithDuration:1 animations^{ label.frame = leftOutsideView;} completion^(BOOL finished){ label.frame = rightOutsideView; label.text = newCaption; [UIView animateWithDuration:1 animations^{ label.frame = originalPlace;}];}];
(This is pseudo code)
Try to use animations in that context, it looks good.

Adding a subview to view changes other subviews' frames

A uiviewcontroller has two UIViews and one tableview added in stroyboard ib and connected with IBoutlet
when user click swipe in top uiview, I call following method to change frames of all subview IBoutlet elements. That works.
-(void)hideTopViews
{
[UIView animateWithDuration:0.25 animations:^{
[_overallHealth setHidden:YES];
_overallHealth.frame = CGRectMake(0, 0,self.view.frame.size.width,0);
[_healthBar setHidden:YES];
_sortView.frame = CGRectMake(0, 45,self.view.frame.size.width,_sortView.frame.size.height);
_portfoList.frame = CGRectMake(0, _sortView.frame.origin.x+_sortView.bounds.size.height+50,self.view.frame.size.width,self.view.frame.size.height);
_sortButton.frame = CGRectMake(90, 45,_sortButton.frame.size.width,_sortButton.frame.size.height);
[self.view bringSubviewToFront:_sortButton];
self.navigationItem.leftBarButtonItems=nil;
}];
}
However when I add another subview programmatically to self.view all subviews goes back to their original positions like in storyboard.
-(void)showPortfolioDetailsScreen
{
PortfolioDetails *portView=[[PortfolioDetails alloc] initWithFrame:CGRectMake(300,200,200,200)];
portView.backgroundColor=[UIColor redColor];
[self.view addSubview:portView];
}
How can I fix this?
#tanzolone is on right track, if you are using only portrait mode and want your storyboard to stop changes your subviews to original frames go to your storyboard and uncheck Use Autolayout
so you can use the old struts-and-springs model.
here is a detailed tutorial of autolayouts though
http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

Resources