Laying out equal sections on a view in xcode - ios

Im wanting to setup my view within the storyboard so it lays out like the above image. The view has 2 seperate sections when landscape the share 50/50 horizontally then when portrait it rotates to 50/50 vertically.
What is the most appropriate way to set this up inside xcode interface builder? Can I use constraints to achieve this? This will need to be designed so it will scale to ipad and iphone as well.

I build a project to test. It works, check the screenshot
iPad in Portrait
iPad in Landscape
It can't be done in Storyboard, because iPad only got one layout in Storyboard.
but it's very simple to achieve what you need programmatically .
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UIView *firstView;
#property (nonatomic, strong) UIView *secondView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.firstView = [[UIView alloc] initWithFrame:CGRectZero];
self.firstView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.firstView];
self.secondView = [[UIView alloc] initWithFrame:CGRectZero];
self.secondView.backgroundColor = [UIColor blueColor];
[self.view addSubview:self.secondView];
[self setupSubViewLayout];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self setupSubViewLayout];
}
- (void)setupSubViewLayout {
CGFloat viewWidth = self.view.frame.size.width;
CGFloat viewHeight = self.view.frame.size.height;
CGRect firstRect;
CGRect secondRect;
if (viewWidth > viewHeight) {
firstRect = CGRectMake(0, 0, viewWidth/2.0, viewHeight);
secondRect = CGRectMake(viewWidth/2.0, 0, viewWidth/2.0, viewHeight);
}else {
firstRect = CGRectMake(0, 0, viewWidth, viewHeight/2.0);
secondRect = CGRectMake(0, viewHeight/2.0, viewWidth, viewHeight/2.0);
}
self.firstView.frame = firstRect;
self.secondView.frame = secondRect;
}

Related

Cannot pan UIScrollView after zooming

I've programatically created a UIScrollView using the following code:
.h:
#interface MainController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, retain) UIScrollView *mainScrollView;
#property (nonatomic, retain) UIView *mainView;
.m:
- (void) initVariables
{
// Setters
screenRect = [[UIScreen mainScreen] bounds];
screenWidth = screenRect.size.width;
screenHeight = screenRect.size.height;
// Alloc-init methods
mainScrollView = [[UIScrollView alloc] init];
mainView = [[UIView alloc] init];
}
- (void) setUpScrollView
{
mainScrollView.frame = CGRectMake(0.0f, 0.0f, screenWidth, screenHeight);
mainScrollView.contentSize = CGSizeMake(screenWidth*2, screenHeight*2);
mainScrollView.minimumZoomScale = 1.0;
mainScrollView.maximumZoomScale = 4.0;
mainScrollView.backgroundColor = [UIColor blueColor];
mainScrollView.scrollEnabled = YES;
mainScrollView.delegate = self;
mainView.frame = CGRectMake((screenWidth/2) - 25.0f, (screenHeight/2) - 25.0f, 50.0f, 50.0f);
UIImageView *testImageView = [[UIImageView alloc] init];
testImageView.backgroundColor = [UIColor redColor];
testImageView.frame = CGRectMake(0.0f, 0.0f, 50.0f, 50.0f);
// Add subviews
[self.view addSubview:mainScrollView];
[mainScrollView addSubview:mainView];
[mainView addSubview:testImageView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return mainView;
}
The zoom works well now. However, I can only pan when the UIScrollView is at the minimum zoom. All other times, when I pinch-zoom in, when I release my fingers the UIView shifts slightly off-centre, despite being centred when I was zooming, and I can no longer pan the UIScrollView.
Also, after zooming in, if I zoom back out again to minimum zoom, I still cannot pan.
TL;DR - In other words, UIScrollView's pan only before using the pinch zoom feature, after which it breaks.
How can I prevent this from happening, and allow the UIScrollView's pan to always be enabled? All help appreciated.
Try to add another view in scrollView with same size of screen and then add mainView and imageView. It may solve your proble. :)

How to change the size of your custom UIView in iOS

I want to use custom view as a toolbar at bottom of my view controller and then design it in my own way. I am using UIView for this purpose and then add as a subview. Somehow, the height of my custom tool bar is not changing. Even, I turned off constraints for it but somehow, it auto adjusts. How can, I do this? Below is my code snippet.
//CameraActivity.h class
#interface CameraActivity : UIViewController
//Custom UIView.
#property (nonatomic, strong) UIView *toolbar;
#end
//CameraActivity.m class, in viewDidLoad.
_toolbar.translatesAutoresizingMaskIntoConstraints = YES;
[self.view removeConstraints:self.view.constraints];
[_toolbar removeConstraints:_toolbar.constraints];
CGRect frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
_toolbar = [[UIView alloc]initWithFrame:frame];
[_toolbar setBackgroundColor:[UIColor colorWithRed:116.0/255.0 green:174.0/255.0 blue:220.0/255.0 alpha:0.75]];
[self.view addSubview:_toolbar];
Make an outlet of your UIView height constraint. Then try to change its height based on device's type as follow:-
In ViewController.h file, Create an outlet:-
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewHeightConstraint;
In ViewController.m file, Change your height's constraint like this:-
if (Device is iPhone 4s) {
viewHeightConstraint.constant = 30.0; //Your desired height
}
else if (Device is iPhone 5 || Device is iPhone 5s || Device is iPhone 5c) {
viewHeightConstraint.constant = 40.0; //Your desired height
}
else if (Device is iPhone 6) {
viewHeightConstraint.constant = 50.0; //Your desired height
}
else if (Device is iPhone 6 Plus) {
viewHeightConstraint.constant = 60.0; //Your desired height
}
Happy Coding!!
Before creating (i.e _toolbar = [[UIView alloc]initWithFrame:frame];) your view toolbar, using it will cause this issue.
Hence, change the line order to this :
CGRect frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
_toolbar = [[UIView alloc]initWithFrame:frame];
_toolbar.translatesAutoresizingMaskIntoConstraints = YES;
[self.view removeConstraints:self.view.constraints];
[_toolbar removeConstraints:_toolbar.constraints];
[_toolbar setBackgroundColor:[UIColor colorWithRed:116.0/255.0 green:174.0/255.0 blue:220.0/255.0 alpha:0.75]];
[self.view addSubview:_toolbar];
Also I suggest setting frame must done in
-(void) viewDidLayoutSubviews beacause viewDidLoad is not a good place for this! so,
-(void) viewDidLayoutSubviews
{
_toolbar.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
}
I added UIView from objects library instead of adding it programmatically and then sets its width according to screen width of device and height to constant. Also assigned some constraints solve my problem.
//CameraActivity.h class
#interface CameraActivity : UIViewController
//This time not custom UIView but IBOutlet.
#property (nonatomic, strong) IBOutlet UIView *toolbar;
#end
//CameraActivity.m class
#import "CameraActivity.h"
#implementation CameraActivity
-(void)viewDidLoad
{
[super viewDidLoad];
//Get your device screen width.
CGFloat width = [UIScreen mainScreen].bounds.size.width;
_toolbar.frame = CGRectMake(0, 44, width, 150);
}

iOS 7 zooming is not working in ScrollView with AutoLayout but working in iOS8/9

I have made a demo for zoom image using UIScrollView. My ViewController only contains one image.
The problem is the image cannot zoom in iO7 (I have tested on iPhone4S-iOS7) but work perfectly in iOS8/iOS9.
Any ideas on how to fix it?
Here is my code
#import "ViewController.h"
#interface ViewController ()<UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIScrollView *scrollview;
#property (weak, nonatomic) IBOutlet UIView *contentview;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
float minimumScale = [_contentview frame].size.width /[_scrollview frame].size.width;
_scrollview.maximumZoomScale = 5; //Change as per you need
_scrollview.minimumZoomScale = minimumScale; //Change as you need
_scrollview.zoomScale = minimumScale;
_scrollview.delegate =self;
_scrollview.clipsToBounds = YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.contentview;
}
#end
Here is the layout structure
Screen.png constraint
ContentView constraint
ScrollView constraint
Here is my demo project
https://drive.google.com/file/d/0B679aXO0SBmMeUVHTUdOcmxJSXM/view
The height and width constraints are causing this in iOS 7. A workaround would be, removing those constraints for iOS 7 and calculate minimumScale manually. in IOS 8 and above, do not change anything.
- (void)viewDidLoad {
[super viewDidLoad];
float minimumScale = 1;
if (floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_8_0) {
[self.view removeConstraints:self.heightWidthConstraints];
minimumScale = self.scrollview.frame.size.width / self.imageView.image.size.width;
}
_scrollview.maximumZoomScale = 5; //Change as per you need
_scrollview.minimumZoomScale = minimumScale; //Change as you need
//_scrollview.zoomScale = minimumScale;
_scrollview.delegate = self;
//_scrollview.clipsToBounds = YES;
[self.scrollview setZoomScale:minimumScale animated:YES];
}
Remove width and height contraint of contentView.
Add centralHorizontal constraint of contentView with scrollView
Let me know if it works.

UIScrollView for image pages not scrolling to next page

I have a UIImageView that contains four ImageView as subviews. Each ImageView acts as a page that the user can scroll forward and go to the next page (image). However, i am unable to achieve this scrolling to next page. It only shows the first image. Here is my implementation
TutorialViewController.h
#import <UIKit/UIKit.h>
#interface TutorialViewController : UIViewController{
}
#property (nonatomic, retain) IBOutlet UIScrollView *tutorialScrollView;
#end
TutorialViewController.m
#import "TutorialViewController.h"
#interface TutorialViewController () <UIScrollViewDelegate>
#end
#implementation TutorialViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tutorialScrollView.pagingEnabled = YES;
self.tutorialScrollView.showsHorizontalScrollIndicator = NO;
self.tutorialScrollView.scrollEnabled = YES;
self.tutorialScrollView.delegate = self;
}
-(void)viewDidAppear:(BOOL)animated
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
UIImageView *page1 = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,screenWidth,screenHeight)];
page1.image = [UIImage imageNamed:#"tutorial1.png"];
UIImageView *page2 = [[UIImageView alloc] initWithFrame:CGRectMake(screenWidth * 2,0,screenWidth,screenHeight)];
page2.image = [UIImage imageNamed:#"tutorial2.png"];
UIImageView *page3 = [[UIImageView alloc] initWithFrame:CGRectMake(screenWidth * 3,0,screenWidth, screenHeight)];
page3.image = [UIImage imageNamed:#"tutorial3.png"];
UIImageView *page4 = [[UIImageView alloc] initWithFrame:CGRectMake(screenWidth * 4,0,screenWidth, screenHeight)];
page4.image = [UIImage imageNamed:#"tutorial4.png"];
[self.tutorialScrollView addSubview:page1];
[self.tutorialScrollView addSubview:page2];
[self.tutorialScrollView addSubview:page3];
[self.tutorialScrollView addSubview:page4];
}
#end
You should set contentSize for UIScrollView:
[self.tutorialScrollView setContentSize:CGSizeMake(screenWidth*numOfPages, screenHeight)];
You will need to set the ContentSize of the scrollView.
self.tutorialScrollView.contentSize = CGSizeMake(imageView.frame.size.width * numberOfImages, self.tutorialScrollView.frame.size.height);
This will scroll your scrollView in horizontal direction.

Show partial content of image using animation

I am working with images in iOS. So when a user presses let's say a button, I want an image to appear to fill up from the bottom to the top.
In order be more precise, imagine a thermometer that is empty and when you press a button the thermometer fills up from the bottom to the top. But I want this with animation.
Do you have any idea how to implement that?
Thanks!
You can easily do it by having a second view acting as a mask over the image view with your image. Then you can apply simple scale transform and animate it revealing the image. Alternatively, you can animate the frame change. Effect will be the same. I'm attaching code for 2 ways of doind this.
Here is what I achieved in both cases:
Code I used for the case I:
#interface MyViewController ()
#property(nonatomic, strong) UIImageView *imageView;
#property(nonatomic, strong) UIView *maskView;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Image"]];
_imageView.center = self.view.center;
_imageView.layer.anchorPoint = CGPointMake(0.5, 0.0);
[self.view addSubview:_imageView];
_maskView = [[UIView alloc] initWithFrame:_imageView.frame];
_maskView.backgroundColor = [UIColor whiteColor];
_maskView.center = self.view.center;
_maskView.layer.anchorPoint = CGPointMake(0.5, 0.0);
[self.view addSubview:_maskView];
}
- (IBAction)buttonTapped:(id)sender
{
[UIView animateWithDuration:1.0f
animations:^
{
_maskView.transform = CGAffineTransformMakeScale(1.0, 0.0001);
}];
}
#end
Code I used for the case II:
#interface MyViewController ()
#property(nonatomic, strong) UIImageView *imageView;
#property(nonatomic, assign) CGFloat height;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Image"]];
_imageView.center = self.view.center;
_imageView.contentMode = UIViewContentModeBottom;
_height = CGRectGetHeight(_imageView.bounds);
CGRect frame = _imageView.frame;
frame.size.height = 0.00001;
frame.origin.y += _height;
_imageView.frame = frame;
_imageView.clipsToBounds = YES;
[self.view addSubview:_imageView];
}
- (IBAction)buttonTapped:(id)sender
{
[UIView animateWithDuration:1.0f
animations:^
{
CGRect frame = _imageView.frame;
frame.size.height = _height;
frame.origin.y -= _height;
_imageView.frame = frame;
}];
}
#end
In both cases the end effect was the same.
You can do this by changing the frame of the view within the animate block. For example, if myView was a 100x100 sized view:
myView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height, 0, 0);
[UIView animateWithDuration:1.0f
animations:^
{
myView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height, 100, 100);
}];
This example should enlarge a 100x100 view in the bottom left corner of the screen, making it appear to reveal itself from the bottom up.

Resources