How can we reduce code using Autolayouts in ios - ios

Hi i am beginner for auto-layouts and i am inserting "3" textfields and "1" button on scrollview
Here my requirement is according i-phone inches "Top space" must be Adjusting and when i click textfield all fields must be scrolling above keyboard and when i click "return" button in keyboard then scroll must be scrolling as like previous
For this i have tried below code but that is too length code can anybody explain me this concept using short process
my code:-
#import "ViewController10.h"
#interface ViewController10 ()
{
UIScrollView * scrollView;
UITextField * emailTextField;
UITextField * nameTextField;
UITextField * passwword;
UIButton * submit;
NSDictionary * viewsDic;
NSArray * verticalConstraints;
int height;
}
#end
#implementation ViewController10
- (void)viewDidLoad {
[super viewDidLoad];
height = [UIScreen mainScreen].bounds.size.height;
scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:scrollView];
emailTextField = [self createLabelWithText];
emailTextField.delegate = self;
[scrollView addSubview: emailTextField];
nameTextField = [self createLabelWithText];
nameTextField.delegate = self;
[scrollView addSubview: nameTextField];
passwword = [self createLabelWithText];
passwword.delegate = self;
[scrollView addSubview: passwword];
submit = [[UIButton alloc]init];
submit.backgroundColor = [UIColor orangeColor];
[submit setTitle: #"Submit" forState: UIControlStateNormal];
submit.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:submit];
viewsDic = NSDictionaryOfVariableBindings(scrollView,emailTextField,nameTextField,passwword,submit);
//Applying autolayouts for scrolview
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-0-[scrollView]-0-|"]
options:0
metrics:nil
views:viewsDic]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"V:|-0-[scrollView]-0-|"]
options:0
metrics:nil
views:viewsDic]];
//Applying autolayouts for textfields and button
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:emailTextField
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:scrollView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
NSArray * keys = #[#"emailTextField",#"nameTextField",#"passwword",#"submit"];
for (NSString * key in keys) {
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-10-[%#]-10-|",key]
options:0
metrics:nil
views:viewsDic]];
}
if (height == 480.0) {
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-30-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
else if (height == 568.0){
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-50-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
else if(height == 667.0){
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-80-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
[scrollView addConstraints:verticalConstraints];
}
-(UITextField *)createLabelWithText{
UITextField * textfield = [[UITextField alloc] init];
textfield.textColor = [UIColor whiteColor];
textfield.backgroundColor = [UIColor lightGrayColor];
textfield.translatesAutoresizingMaskIntoConstraints = NO;
return textfield;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
scrollView.contentSize = CGSizeMake(320, 700);
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
[scrollView removeConstraints:verticalConstraints];
if (height == 480.0) {
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-30-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
else if (height == 568.0){
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-50-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
else if(height == 667.0){
verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-80-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic];
}
[scrollView addConstraints:verticalConstraints];
return YES;
}
#end

try masonry,it can reduce the code and it is easier for you to maintain and understand
https://github.com/SnapKit/Masonry

Related

UIScrollView with horizontal paging` does not center subview

I am trying to use UIScrollView with paging enabled. I am adding various UIView to UISCrollView as a subviews. I want those subview to be smaller than size of scroll view so I have modified my constrains accordingly. Now when I actually swipe them left/ right then do not happened to be in center. I was expecting it to show previous / next view peeking from sides with current page in center.
This is what it looks like
Below is my code scrollview implementation
//
// ViewController.m
// Paging
//
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UIScrollView *pagingScrollView;
#end
#implementation ViewController
- (UIScrollView *)pagingScrollView {
if (!_pagingScrollView) {
_pagingScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
_pagingScrollView.translatesAutoresizingMaskIntoConstraints = NO;
_pagingScrollView.backgroundColor = [UIColor orangeColor];
_pagingScrollView.showsHorizontalScrollIndicator = NO;
_pagingScrollView.showsVerticalScrollIndicator = NO;
_pagingScrollView.contentInset = UIEdgeInsetsZero;
_pagingScrollView.pagingEnabled = YES;
_pagingScrollView.clipsToBounds = NO;
_pagingScrollView.bounces = NO;
}
return _pagingScrollView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self scrollViewSetUp];
NSDictionary *views = NSDictionaryOfVariableBindings(_pagingScrollView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[_pagingScrollView]|"
options:0
metrics:nil
views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_pagingScrollView]|"
options:0
metrics:nil
views:views]];
}
- (void)scrollViewSetUp {
[self.view addSubview:self.pagingScrollView];
UIView *lastView = nil;
NSInteger arrayCount = 5;
for(NSInteger index = 0; index < arrayCount; index++)
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.translatesAutoresizingMaskIntoConstraints = NO;
view.backgroundColor = [UIColor yellowColor];
[self.pagingScrollView addSubview:view];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeTop
multiplier:1
constant:40]];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeHeight
multiplier:0.80
constant:0]];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeWidth
multiplier:0.80
constant:0]];
if (lastView == nil && index == 0){
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-20-[view(==_pagingScrollView)]"
options:0
metrics:nil
views:#{#"view":view, #"_pagingScrollView":_pagingScrollView}]];
} else {
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[lastView]-20-[view]"
options:0
metrics:nil
views:#{#"lastView":lastView, #"view":view, #"_pagingScrollView":_pagingScrollView}]];
}
if(index == arrayCount-1) {
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[view]-20-|"
options:0
metrics:nil
views:#{#"view":view}]];
}
lastView = view;
}
}
#end
Any pointers/comments/feedback highly appreciated. Thanks.
Is this you want?
//
// ViewController.h
// Test
//
// Created by Lee on 7/8/16.
// Copyright © 2016 Lee. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, strong) UIScrollView *pagingScrollView;
#end
//
// ViewController.m
// Test
//
// Created by Lee on 7/8/16.
// Copyright © 2016 Lee. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()<UIScrollViewDelegate>
#property (nonatomic,strong)NSMutableArray *subviewsCenterArray;
#end
#implementation ViewController
- (UIScrollView *)pagingScrollView {
if (!_pagingScrollView) {
_pagingScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
_pagingScrollView.translatesAutoresizingMaskIntoConstraints = NO;
_pagingScrollView.backgroundColor = [UIColor orangeColor];
_pagingScrollView.showsHorizontalScrollIndicator = NO;
_pagingScrollView.showsVerticalScrollIndicator = NO;
_pagingScrollView.contentInset = UIEdgeInsetsZero;
_pagingScrollView.pagingEnabled = NO;
_pagingScrollView.clipsToBounds = NO;
_pagingScrollView.bounces = NO;
_pagingScrollView.delegate = self;
}
return _pagingScrollView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self scrollViewSetUp];
NSDictionary *views = NSDictionaryOfVariableBindings(_pagingScrollView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[_pagingScrollView]|"
options:0
metrics:nil
views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_pagingScrollView]|"
options:0
metrics:nil
views:views]];
}
- (void)scrollViewSetUp {
[self.view addSubview:self.pagingScrollView];
UIView *lastView = nil;
NSInteger arrayCount = 5;
_subviewsCenterArray = [NSMutableArray array];
for(NSInteger index = 0; index < arrayCount; index++)
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.translatesAutoresizingMaskIntoConstraints = NO;
view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
view.tag = 9999;
view.layer.cornerRadius = 6;
[self.pagingScrollView addSubview:view];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeTop
multiplier:1
constant:40]];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeHeight
multiplier:0.80
constant:0]];
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeWidth
multiplier:0.80
constant:0]];
if (lastView == nil && index == 0){
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-20-[view(==_pagingScrollView)]"
options:0
metrics:nil
views:#{#"view":view, #"_pagingScrollView":_pagingScrollView}]];
} else {
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[lastView]-20-[view]"
options:0
metrics:nil
views:#{#"lastView":lastView, #"view":view, #"_pagingScrollView":_pagingScrollView}]];
}
if(index == arrayCount-1) {
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[view]-20-|"
options:0
metrics:nil
views:#{#"view":view}]];
}
[self.view layoutIfNeeded];
lastView = view;
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
[self changeTheCardStatus:scrollView];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self changeTheCardStatus:scrollView];
}
-(void)changeTheCardStatus:(UIScrollView *)scrollView{
for (UIView *view in scrollView.subviews) {
if (view.tag == 9999) {
[_subviewsCenterArray addObject:#(view.center.x)];
}
}
CGFloat currentCenterOffsetX = scrollView.contentOffset.x + CGRectGetWidth(self.view.frame)/2.0;
NSMutableArray *absoluteValueArray = [NSMutableArray array];
NSMutableDictionary *absoluteValueDictionary = [NSMutableDictionary dictionary];
for (int i = 0; i < _subviewsCenterArray.count; i ++) {
float subviewsCenterPointX = [_subviewsCenterArray[i] floatValue];
double absolute = fabs(subviewsCenterPointX - currentCenterOffsetX);
[absoluteValueArray addObject:#(absolute)];
[absoluteValueDictionary setValue:#(subviewsCenterPointX) forKey:[NSString stringWithFormat:#"%f",absolute]];
}
[absoluteValueArray sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
double a = [obj1 doubleValue];
double b = [obj2 doubleValue];
if (a>b) {
return NSOrderedDescending;
}
else if (a<b){
return NSOrderedAscending;
}
else{
return NSOrderedSame;
}
}];
double shortValue = [absoluteValueArray.firstObject doubleValue];
double centerX = [[absoluteValueDictionary objectForKey:[NSString stringWithFormat:#"%f",shortValue]] doubleValue];
[UIView animateWithDuration:0.25 animations:^{
scrollView.contentOffset = CGPointMake(centerX - CGRectGetWidth(self.view.frame)/2.0, 0);
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Of course It's not. The subview of pagingScrollView doesn't have a right width! Also these subviews don's have correct horizontal margin.
First You should correct your setting width code, change the multiplier to 1 and constant to -40. Like this:
[self.pagingScrollView addConstraint:[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.pagingScrollView
attribute:NSLayoutAttributeWidth
multiplier:1
constant:-40]];
Then modify the subview margin, change -20 to -40, like this
[self.pagingScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[lastView]-40-[view]"
options:0
metrics:nil
views:#{#"lastView":lastView, #"view":view, #"_pagingScrollView":_pagingScrollView}]];

How to show UIView like UIAction sheet using UIView animations in iOS?

Hi I am very new for iOS and I have added a UIView at bottom of MainViewController.
And when I tap on a button that UIView displays like "UIAction sheet" using UIView animations.
And for this I have tried the code below but animations are not applying when I tap on the button.
Please help me.
my code:-
#import "AnimationUIview.h"
#interface AnimationUIview ()
{
UIView * firstView;
NSLayoutConstraint * Bottom;
}
#end
#implementation AnimationUIview
- (void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIView alloc] init];
firstView.backgroundColor = [UIColor lightGrayColor];
firstView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:firstView];
NSDictionary * views = NSDictionaryOfVariableBindings(firstView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[firstView]-0-|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[firstView(100)]" options:0 metrics:nil views:views]];
Bottom = [NSLayoutConstraint constraintWithItem:firstView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:80];
[self.view addConstraint:Bottom];
}
- (IBAction)buttonAction:(id)sender {
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
Bottom.constant = -10;
}
completion:nil];
}
#end
#import "AnimationUIview.h"
#interface AnimationUIview () {
UIView * firstView;
NSLayoutConstraint * Bottom;
BOOL isshown;
}
#end
#implementation AnimationUIview
-(void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIView alloc] init];
firstView.backgroundColor = [UIColor lightGrayColor];
firstView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:firstView];
NSDictionary * views = NSDictionaryOfVariableBindings(firstView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[firstView]-0-|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[firstView(100)]" options:0 metrics:nil views:views]];
Bottom = [
NSLayoutConstraint
constraintWithItem:firstView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:80
];
[self.view addConstraint:Bottom];
isshown=No;
}
- (IBAction)buttonAction:(id)sender {
if (isshown==NO) {
firstview.frame = CGRectMake(0,0, SCREEN_WIDTH, 100);
[UIView animateWithDuration:0.40 animations:^{
firstview.frame = CGRectMake(0, SCREEN_HEIGHT-100, SCREEN_WIDTH, 100);
[firstview setAlpha:0.0f];
} completion:^(BOOL finished) {
}];
isshow=Yes;
} else {
firstview.frame = CGRectMake(0, SCREEN_HEIGHT-100, SCREEN_WIDTH, 100);
[UIView animateWithDuration:0.40 animations:^{
firstview.frame = CGRectMake(0,0, SCREEN_WIDTH, 100);
firstview.alpha = 1.0f;
} completion:^(BOOL finished) {
[firstview setHidden:YES];
}];
isshown=No;
}
#end

How to change scrollView content sizes using auto-layouts in ios

I am adding 3 UITextfields and 1 UIButton on my scrollview.
My main requirement is when I click on UITextfield scroll must scroll up-to all fields visible to user above keyboard.
And when I click return button on keyboard scroll must scroll by default what in set for scrollview contentSize using auto-layouts.
my code:
#interface ViewController10 ()
{
UIScrollView * scrollView;
UITextField * emailTextField;
UITextField * nameTextField;
UITextField * passwword;
UIButton * submit;
}
#end
#implementation ViewController10
- (void)viewDidLoad {
[super viewDidLoad];
scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:scrollView];
emailTextField = [self createLabelWithText];
emailTextField.delegate = self;
[scrollView addSubview: emailTextField];
nameTextField = [self createLabelWithText];
nameTextField.delegate = self;
[scrollView addSubview: nameTextField];
passwword = [self createLabelWithText];
passwword.delegate = self;
[scrollView addSubview: passwword];
submit = [[UIButton alloc]init];
submit.backgroundColor = [UIColor orangeColor];
[submit setTitle: #"Submit" forState: UIControlStateNormal];
submit.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:submit];
NSDictionary * viewsDic = NSDictionaryOfVariableBindings(scrollView,emailTextField,nameTextField,passwword,submit);
//Applying autolayouts for scrolview
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-0-[scrollView]-0-|"]
options:0
metrics:nil
views:viewsDic]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"V:|-0-[scrollView]-0-|"]
options:0
metrics:nil
views:viewsDic]];
//Applying autolayouts for textfields and button
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:emailTextField
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:scrollView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
NSArray * keys = #[#"emailTextField",#"nameTextField",#"passwword",#"submit"];
for (NSString * key in keys) {
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-10-[%#]-10-|",key]
options:0
metrics:nil
views:viewsDic]];
}
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-30-[emailTextField(30)]-130-[nameTextField(30)]-130-[passwword(30)]-60-[submit(30)]-20-|"
options:0
metrics:nil
views:viewsDic]];
}
-(UITextField *)createLabelWithText{
UITextField * textfield = [[UITextField alloc] init];
textfield.textColor = [UIColor whiteColor];
textfield.backgroundColor = [UIColor lightGrayColor];
textfield.translatesAutoresizingMaskIntoConstraints = NO;
return textfield;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
scrollView.contentSize = CGSizeMake(320, 700);
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Please check this awsome tutorial , it is definetly helpfull for you.
**
Using UIScrollView with Auto Layout in iOS
**
as said in blog you need to set constrain in this way when you are using autolayout.
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeLeading
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0];
[self.view addConstraint:leftConstraint];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeTrailing
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0];
[self.view addConstraint:rightConstraint];
change value and name according to your requirement.
When keyBoards is appears .
CGRect frame = currentActiveView.frame; // your scrollview frame
frame.size.height = SCREEN_HEIGHT - 216 - keyboardAccesssory.frame.size.height;
currentActiveView.frame = frame;
[yourScrollView setContentSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT)];
When keyboard is resign ..
CGRect frame = currentActiveView.frame; // your scrollview frame
frame.size.height = SCREEN_HEIGHT;
currentActiveView.frame = frame;
[yourScrollView setContentSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT)];
You need to play with the frame of the view.
Move the frame above keyboard when keyboard is shown whereas reset its position when keyboard is hidden.
You need to do it programmatically.
You can also go through Apple's Programming guide. https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW3

scrollView: how to create a pure auto layout scrollview with paging?

Can someone tell me what I did wrong here...
- pin the UIScrollView to its container view
- pin all subviews onto UIScrollView
After reading the Apple TechNote about it, I tried both hybrid method and pure auto layout method. The hybrid method using NIB works awful with paging, it looks like a big picture in a scrollview, rather than paged.
I then created the pure auto layout version in code, UIScrollView as subview of a UIView. This time the view stuck, and the UIImage is gigantic, like its full size:
//scroll view
if (self.scrollView == nil)
{
self.scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView setClipsToBounds:NO];
[self.scrollView setPagingEnabled:YES];
[self addSubview: self.scrollView];
[self addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView(300)]|"
options:0 metrics:nil
views:#{#"scrollView":self.scrollView}]];
[self addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrollView(300)]|"
options:0 metrics:nil
views:#{#"scrollView":self.scrollView}]];
-(void) createContentView
{
for (int i=0; i<self.pageImages.count; i++) {
UILabel* topLabel = [[UILabel alloc] init];
topLabel.text = [NSString stringWithFormat:#"topLabel %d", i+1];
[topLabel sizeToFit];
[self.topLabelArray insertObject:topLabel atIndex:i];
[self.scrollView addSubview:topLabel];
topLabel.translatesAutoresizingMaskIntoConstraints = NO;
UILabel* bottomLabel = [[UILabel alloc] init];
bottomLabel.text = [NSString stringWithFormat:#"bottomLabel %d", i+1];
[bottomLabel sizeToFit];
[self.bottomLabelArray insertObject:bottomLabel atIndex:i];
[self.scrollView addSubview:bottomLabel];
bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;
UIButton* button = [[UIButton alloc] init];
button.titleLabel.text = [NSString stringWithFormat:#"button %d", i+1];
[button sizeToFit];
[self.buttonArray insertObject:button atIndex:i];
[self.scrollView addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.pageImages objectAtIndex:i]]];
imageView.frame = CGRectMake(0,0,200,200);
imageView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.pageViews insertObject:imageView atIndex:i];
[self.scrollView addSubview:imageView];
NSDictionary* viewsDictionary = #{#"topLabel":topLabel,
#"bottomLabel":bottomLabel,
#"button": button,
#"imageView": imageView
};
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(10)-[topLabel]-(10)-[imageView]-(10)-[bottomLabel]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:[button]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
if (i==0)
{
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(10)-[topLabel]"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(10)-[imageView]"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(10)-[bottomLabel]-(10)-[button]"
options:0 metrics:nil
views:viewsDictionary]];
}
else if (i == self.pageImages.count)
{
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[topLabel]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[imageView]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[bottomLabel]-(10)-[button]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
}
else
{
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[prevTopLabel]-(10)-[topLabel]"
options:0 metrics:nil
views:#{#"prevTopLabel": [self.topLabelArray objectAtIndex: i-1],
#"topLabel": topLabel
}]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[prevImageView]-(10)-[imageView]"
options:0 metrics:nil
views:#{#"prevImageView": [self.pageViews objectAtIndex: i-1],
#"imageView": imageView
}]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[prevButton]-(10)-[bottomLabel]-(10)-[button]"
options:0 metrics:nil
views:#{#"prevButton": [self.buttonArray objectAtIndex: i-1],
#"button":button,
#"bottomLabel": bottomLabel
}]];
}
[self.scrollView addConstraint:[NSLayoutConstraint
constraintWithItem:topLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:imageView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0.0]];
[self.scrollView addConstraint:[NSLayoutConstraint
constraintWithItem:bottomLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:imageView
attribute:NSLayoutAttributeCenterX
multiplier:0.8
constant:0.0]];
// [self.scrollView addConstraint:[NSLayoutConstraint
//
Ok, there's a few things wrong here:
else if (i == self.pageImages.count)
This clause will never run, as your loop count is set to break when i == self.pageImages.count -1, here for (int i=0; i<self.pageImages.count; i++).
Next
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[topLabel]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[imageView]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
[self.scrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:-(10)-[bottomLabel]-(10)-[button]-(10)-|"
options:0 metrics:nil
views:viewsDictionary]];
These will also produce invalid constraints, specifically #"H:-(10)-[bottomLabel].... is not pinning the furthest left constraint to anything. All visual format strings that connect views need to start or finish with a view. Either a subview ([subview]) or a superview (|). To fix this, you need to keep a reference to the previous pages label in the loop, and add that to the beginning of your VFL string. Something like this
#"H:[prevBottomLabel]-(10)-[bottomLabel]....
prevBottomLabel = bottomLabel;
// Continue loop
Next:
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.pageImages objectAtIndex:i]]];
imageView.frame = CGRectMake(0,0,200,200);
imageView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.contentMode = UIViewContentModeScaleAspectFit;
This will not have the desired effect, as you can't manually set the frame, then switch on autolayout. Currently, the frame value is ignored, and the height and width are set by the intrinsic content size of the image view, which will be the height and width of the image. If you want to set the height and width, you need to do it with constraints, as so:
[imageView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[imageView(200)]"
options:0 metrics:nil
views:viewsDictionary]];
[imageView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:[imageView(200)]"
options:0 metrics:nil
views:viewsDictionary]];
That should give you some pointers, there may be other mistakes in there too but fixing these is a good place to start.

uitableview drag down outside screen

I'm basically trying to achieve this effect: http://youtu.be/VBW2i0P11iI
The tableview is a basic one that's pinned to it's superview with autolayout. The view underneath is added with the classic insertSubview:belowSubview: / addChildViewController combo.
I've tried a couple of approaches. What I have now is:
if (scrollOffset >= -scrollView.contentInset.top) {
self.resultsTableViewContainerTopConstraint.constant = 0;
} else {
self.resultsTableViewContainerTopConstraint.constant = MAX(self.resultsTableViewContainerTopConstraint.constant, self.resultsTableViewContainerTopConstraint.constant - scrollDiff);
}
}
So I'm basically changing the top constraint based on the delta of contentOffset. The problem with this is that the uitableview bounces back so it always gets into the first branch of the if. But even if I solve this problem I feel like I'll just patch it. I'm sure there's a way more elegant way of achieving the effect in the video having the same responsiveness.
Any suggestion will be much appreciated.
Thanks
I'm not sure if this is what you want but I hacked up a quick demo:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate>
#property (nonatomic, strong) UIView *headerView;
#property (nonatomic, strong) UILabel *lblTitle;
#property (nonatomic, strong) UIButton *btnReset;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) UIScrollView *scrollView;
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, strong) NSLayoutConstraint *scrollViewTopConstraint;
#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.view.backgroundColor = [UIColor whiteColor];
[self initViews];
[self initConstraints];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)initViews
{
self.view.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.alwaysBounceVertical = YES;
self.scrollView.delegate = self;
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.headerView.layer.shadowColor = [UIColor blackColor].CGColor;
self.headerView.layer.shadowOffset = CGSizeMake(0,0);
self.headerView.layer.shadowOpacity = 0.25;
self.headerView.layer.shadowRadius = 4;
self.lblTitle = [[UILabel alloc] init];
self.lblTitle.text = #"HEADER VIEW";
self.lblTitle.textColor = [UIColor whiteColor];
self.lblTitle.textAlignment = NSTextAlignmentCenter;
self.btnReset = [[UIButton alloc] init];
[self.btnReset setTitle:#"Reset" forState:UIControlStateNormal];
self.btnReset.backgroundColor = [UIColor colorWithRed:0.75 green:0.0 blue:0.0 alpha:1.0];
self.btnReset.layer.cornerRadius = 5.0;
[self.btnReset addTarget:self action:#selector(resetView) forControlEvents:UIControlEventTouchUpInside];
self.imageView = [[UIImageView alloc] init];
self.imageView.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.tableView = [[UITableView alloc] init];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.rowHeight = 150.0;
self.tableView.layer.shadowColor = [UIColor blackColor].CGColor;
self.tableView.layer.shadowOffset = CGSizeMake(0,-5);
self.tableView.layer.shadowOpacity = 0.5;
self.tableView.layer.shadowRadius = 20;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.scrollEnabled = NO;
self.tableView.clipsToBounds = NO;
[self.headerView addSubview:self.lblTitle];
[self.headerView addSubview:self.btnReset];
[self.scrollView addSubview:self.tableView];
[self.view addSubview:self.imageView];
[self.view addSubview:self.scrollView];
[self.view addSubview:self.headerView];
}
-(void)initConstraints
{
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.lblTitle.translatesAutoresizingMaskIntoConstraints = NO;
self.btnReset.translatesAutoresizingMaskIntoConstraints = NO;
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
id views = #{
#"scrollView": self.scrollView,
#"headerView": self.headerView,
#"lblTitle": self.lblTitle,
#"btnReset": self.btnReset,
#"imageView": self.imageView,
#"tableView": self.tableView
};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[scrollView]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
self.scrollViewTopConstraint = [NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
[self.view addConstraint:self.scrollViewTopConstraint];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[headerView(320)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[headerView(50)]" options:0 metrics:nil views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[tableView(320)]|" options:0 metrics:nil views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-150-[tableView(300)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imageView(320)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageView(320)]" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[lblTitle]|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[lblTitle]|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[btnReset(80)]-5-|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-8-[btnReset]-8-|" options:0 metrics:nil views:views]];
}
-(BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark - TableView Methods -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
return cell;
}
#pragma mark - ScrollView Delegate -
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//NSLog(#"scrollView offset = %lf", scrollView.contentOffset.y);
if(scrollView.contentOffset.y <= -145)
{
//self.scrollView.scrollEnabled = NO;
self.scrollViewTopConstraint.constant = self.view.bounds.size.height;
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.scrollView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
}
-(void)resetView
{
self.scrollViewTopConstraint.constant = 0;
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.scrollView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
What you get when you open the app:
Then you drag down to the edge, the view snaps open:
Press the red reset button to bring it back up :D

Resources