My ViewController looks like this when initially loaded:
When show button is tapped it must change like this:
my code is:
- (IBAction)show:(id)sender {
[self change];
[tableView reloadData];
}
- (IBAction)close:(id)sender {
[self change];
[tableView reloadData];
}
-(void)change{
//assigning initial bounds to frame-1
CGRect frame1=CGRectMake(0, _pastProcessTV.frame.origin.y, self.view.bounds.size.width, self.pastProcessTV.bounds.size.height);
//assigning new bounds to frame-2
CGRect frame2=CGRectMake(0, **CGFloat y**,self.view.bounds.size.width,***CGFloat height***);
if (_showFullButton.isTouchInside) {
tableView.frame = frame2;
}
else{
tableview.frame = frame1;
}
}
I tried different ways. it is not working.can anyone help me in giving Y-coordinate and width
As you are using autolayout you have to take outlet of topconstraint of the tableview and when you want to expand it set its value to 0
So it will work as expected
if you are using iOS 7
[self.view layoutIfNeeded] is compulsary
If you have to use auto layout, please try like this picture
Make Layout Constraint Property
And try this code
#import "ViewController.h"
#interface ViewController ()
{
CGFloat oldtableViewTopValue;
}
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewTopLC;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
oldtableViewTopValue = _tableViewTopLC.constant;
}
- (IBAction)showBtnAction:(id)sender
{
[UIView animateWithDuration:0.5f animations:^{
_tableViewTopLC.constant = (_tableViewTopLC.constant==oldtableViewTopValue ? 0 : oldtableViewTopValue);
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
#end
Please turn off autolayout from Storyboard
Related
As the title says, whenever I want to set the text of a UILabel after the animation of the movement of the label, it returns the UILabel back to the origin before the animation. What's interesting is that this only happens when the animation is triggered by a UIButton action.
I've replicated this in a new project. Copy the below code and see what happens.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *hello;
- (IBAction)move:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.hello.text = #"Hello";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)move:(id)sender {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.hello.text = #"Howdy";
});
[UIView animateWithDuration:1.0f animations:^{
self.hello.center = CGPointMake(self.hello.center.x + 50, self.hello.center.y + 50);
}];
}
#end
Where self.hello and move are linked to a UILabel and UIButton in the storyboard.
Playing around with this I can see that this error does not occur when instead of using the self.hello.center, you use self.hello.transform = CGAffineTransformMakeTranslation(50, 50). Why is this? Is there any way to continue using .center or do I have to change all of my animations to .transform?
Thanks for your help.
I've had to give into the ways of .transform
Please use constraints rather then modifying centre of label. Such issue happens when we mix auto layout and coordinate system handling. Which I feel you should do something similar to this :
[UIView animateWithDuration:1.0f animations:^{
self.xPos.constant = self.hello.center.x + 50;
self.yPos.constant = self.hello.center.y + 50;
[self.hello layoutIfNeeded];
} completion:^(BOOL finished) {
self.hello.text = #"Howdy";
}];
where xPos and yPos are x and y NSLayoutConstraint position of UILabel
I want to add a green line below UIButton for selected state, like following image.
I have set content offset for image and title in storyboard but i am facing issue while using auto layouts. Also selected state has image below text and un-selected state has no image below. What is the best way to handle this?
Here is a subclass that I have created for our App.
Header file:
#import <UIKit/UIKit.h>
IB_DESIGNABLE
#interface CMTabButton : UIButton
/// The color for the bottom line of the button when it is selected
#property (nonatomic)IBInspectable UIColor *selectedColor;
/// The color for the bottom line of the button when it is not selected
#property (nonatomic)IBInspectable UIColor *defaultColor;
/// The height of the bottom line of the button (default 2 pixels)
#property(nonatomic,assign)IBInspectable CGFloat bottomLineHeight;
#end
Implementation file:
#import "CMTabButton.h"
#interface CMTabButton() {
UIView *bottomLine;
NSLayoutConstraint *bottomLineHeightConstraint;
}
#end
#implementation CMTabButton
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setup];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)didMoveToWindow {
[super didMoveToWindow];
[self uppdateUI];
}
- (void)setup {
//add the bottom line
[self addBottomLine];
}
- (void)setSelected:(BOOL)selected {
//if the unselected color is transparent, we animate the line in/out by changing the height of the line
if (self.defaultColor==nil) {
bottomLineHeightConstraint.constant = (selected) ? self.bottomLineHeight : 0;
//we force the selected color for the animation so the animation is visible
bottomLine.backgroundColor = self.selectedColor;
[UIView animateWithDuration:0.15
animations:^{
[self layoutIfNeeded];
}
completion:^(BOOL finished) {
if (!selected)
bottomLine.backgroundColor = self.defaultColor;
[super setSelected:selected];
}
];
}
else {
bottomLineHeightConstraint.constant = self.bottomLineHeight;
//else, we animate the color change
[UIView animateWithDuration:0.15
animations:^{
bottomLine.backgroundColor = selected ? self.selectedColor : self.defaultColor;
}
completion:^(BOOL finished) {
[super setSelected:selected];
}
];
}
}
- (void)addBottomLine {
bottomLine = [UIView new];
bottomLine.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:bottomLine];
bottomLineHeightConstraint = [NSLayoutConstraint constraintWithItem:bottomLine attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0];
[self addConstraint:bottomLineHeightConstraint];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[bottomLine]|" options:0 metrics:nil views:#{#"bottomLine":bottomLine}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[bottomLine]|" options:0 metrics:nil views:#{#"bottomLine":bottomLine}]];
}
- (void)prepareForInterfaceBuilder {
[self uppdateUI];
}
- (void)uppdateUI {
bottomLine.backgroundColor = self.selected ? self.selectedColor : self.defaultColor;
if (self.bottomLineHeight>0) {
bottomLineHeightConstraint.constant = self.bottomLineHeight;
[self layoutIfNeeded];
}
}
#end
To use it, select your UIButton on Interface builder, then change the class name of it from UIButton to CMTabButton and then you can set the properties from the Interface builder directly
following image describes the scenario.
http://i.stack.imgur.com/PPm4e.png
On animate button press, the blue screen (or containerView) should move away from view and similarly come back to initial position on repress.
The code is working. But the containerView is not behaving as the subview of some other view. It should not come out of light gray colored view. Which is its super view. It should move up and down within its limits.
The simulator screen shots are as follows :
http://i.stack.imgur.com/SJjA5.png
http://i.stack.imgur.com/I98W8.png
Any suggestions are highly appreciated.
ViewController.m :-
#interface ViewController ()
{
BOOL scrollUp;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.containerBackgroundView addSubview:self.containerview];
scrollUp = NO;
[self animate:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)animate:(id)sender {
if (scrollUp) {
[self rollUpMenuPage];
scrollUp = NO;
}
else
{
scrollUp = YES;
[self unRollTheMenuPage];
}
}
-(void)unRollTheMenuPage
{
NSLog(#"containerview frame before unRoll : %#",[self.containerview description]);
CGRect rect = CGRectMake(self.containerview.frame.origin.x, 0.0f, self.containerview.frame.size.width, self.containerview.frame.size.height);
[UIView animateWithDuration:1.0f
animations:^{
self.containerview.frame = rect;
}
completion:^(BOOL finished){
// do something here if you wish.
NSLog(#"containerview frame after unRoll : %#",[self.containerview description]);
}];
}
-(void)rollUpMenuPage
{
NSLog(#"containerview frame before roll up : %#",[self.containerview description]);
CGRect rect = CGRectMake(self.containerview.frame.origin.x, -self.containerBackgroundView.frame.size.height, self.containerview.frame.size.width, self.containerview.frame.size.height);
[UIView animateWithDuration:1.0f
animations:^{
self.containerview.frame = rect;
}
completion:^(BOOL finished){
NSLog(#"containerview frame after roll up : %#",[self.containerview description]);
}];
}
ViewController.h
#property (weak, nonatomic) IBOutlet UIView *containerBackgroundView;
#property (weak, nonatomic) IBOutlet UIView *containerview;
Current output :-
http://screencast.com/t/bfLmJFYmym4
Issue is, when moving up it should not go above the light gray colored view.
Thanks
Ok, after re-creating your project and testing it you are right the view si drawn outside of it's superView bounds.
To undo this you can click the clip subviews property in the back view, so when the containerView steps out of the backView bounds it will be clipped and will not get drawn
It looks to me like you have added a UINavigationBar (or some other toolBar) up top as a subview of your UIViewController's view, and that containerBackroundView (which is transparent bg colour) is over the top of that bar.
Suggest you alter the frame.origin.y of containerBackgroundView so that it does not cover that top bar there or go beneath the status bar.
I'm trying to position a button so that it is always an X amount of pixels from the bottom of the screen. The view is laid out programmatically using auto layout. If I use: #"V:|-44-[closeModalButton]" the object aligns 44 pixels from the top of the screen as expected. However, #"V:[closeModalButton]-44-|" causes the button to never show up. It seems like it ought to be pretty straightforward, so I feel like I'm missing something really obvious.
Implementation of view
#import "DetailView.h"
#implementation DetailView
#synthesize closeModalButton;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor whiteColor];
CGRect aFrame = [[UIScreen mainScreen] bounds];
self.frame = aFrame;
closeModalButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeModalButton setImage: [UIImage imageNamed:#"closeButton.png"] forState:UIControlStateNormal];
[closeModalButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:closeModalButton];
NSDictionary *viewArranging = NSDictionaryOfVariableBindings(closeModalButton);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[closeModalButton(44)]-44-|"
options:0
metrics:0
views:viewArranging]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-149-[closeModalButton(44)]-149-|"
options:0
metrics:0
views:viewArranging]];
}
return self;
}
#end
View controller
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
{
DetailView *_detailView;
}
- (void)loadView
{
_detailView = [[DetailView alloc] init];
[self setView:_detailView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[_detailView.closeModalButton addTarget:self
action:#selector(closeModalButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)closeModalButtonPressed:(UIButton *)sender{
[self dismissViewControllerAnimated:YES
completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Ok, so it looks like DetailView.h subclassed UIScrollView rather than UIView. Setting the proper subclass caused the constraints to operate as expected.
I need to move an UIImageView from x,y to x,y1.
This is what i have. I tried lots of different codes in -(void)animation, most using animateWithDuration but none seems to work. It just doesn't do anything. I must be missing something. Is .h correct? How would you make the image move? I then have to loop that, how can i do that? It's my first time with animate, I can't figure out what to do, it has to be simple. Thanks in Advance.
in .h I connected it this way
#import <UIKit/UIKit.h>
#interface ImageBeaconViewController : UIViewController {
__weak IBOutlet UIImageView *blueView;
}
#end
the in .m I've got
- (void)viewDidLoad
{
[self animation];
[super viewDidLoad];
}
....
- (void)animation{
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = CGPointMake(blueView.center.x , blueView.center.y +??);
}];
}
??= I still have to decide how much I want it to move
This way the app crashes as soon as I get to the screen with the animation
Add Method Like This:
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = point;
}];
}
Call like this:
- (void) viewDidAppear:(BOOL)animated {
int distanceToSlide = 40; // will slide down 40px (use -40 to go up)
CGPoint targetPoint = CGPointMake(blueView.center.x, blueView.center.y + distanceToSlide);
[self animateToPoint:targetPoint];
}
NOTE
Notice that I put your animation call in viewDidAppear if you animate in viewDidLoad you won't see anything because your view isn't displayed yet.
If it's still not moving, make sure "useAutolayout" is not selected check this:
Just because I already built it, try this for tap to animate:
In your viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]init];
tap.numberOfTapsRequired = 1;
[tap addTarget:self action:#selector(handleTap:)];
[self.view addGestureRecognizer:tap];
}
Then, use these:
- (void) handleTap:(UITapGestureRecognizer *)tap {
int distanceToSlide = 40; // will slide down 40px (use -40 to go up)
CGPoint targetPoint = CGPointMake(blueView.center.x, blueView.center.y + distanceToSlide);
[self animateToPoint:targetPoint];
}
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = point;
}];
}
Here's a way to loop it:
#implementation ImageBeaconViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
pointA = CGPointMake(40, 40);
pointB = CGPointMake(250, 350);
blueView.center = pointA;
}
- (void) viewDidAppear:(BOOL)animated {
[self animate];
}
- (void) animate {
if (CGPointEqualToPoint(_blueView.center, pointA)) {
[self animateToPoint:pointB];
}
else {
[self animateToPoint:pointA];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:1.0 animations:^{
_blueView.alpha = 1;
_blueView.center = point;
} completion:^(BOOL finished) {
if (finished) {
[self animate];
}
}];
}
#end
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
blueView.alpha = 1;
blueView.center = CGPointMake(blueView.center.x , blueView.center.y + 100);
} completion:^(BOOL finished) {
//if you need any thing after animation is done
}];
this is them code for animation i have