Best practice to calculate view size within loadView method - ios

What is the best practice to calculate the view size in the loadView method (in an UIViewController) without a XIB file?
Here is my solution:
- (void)loadView {
//Calculate Screensize
BOOL statusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden ];
BOOL navigationBarHidden = [self.navigationController isNavigationBarHidden];
BOOL tabBarHidden = [self.tabBarController.tabBar isHidden];
CGRect frame = [[UIScreen mainScreen] bounds];
if (!statusBarHidden) {
frame.size.height -= [[UIApplication sharedApplication] statusBarFrame].size.height;
}
if (!navigationBarHidden) {
frame.size.height -= self.navigationController.navigationBar.frame.size.height;
}
if (!tabBarHidden) {
frame.size.height -= self.tabBarController.tabBar.frame.size.height;
}
UIView *v = [[UIView alloc] initWithFrame: frame];
[v setBackgroundColor: [UIColor whiteColor] ];
[v setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ];
[self setView: v ];
[v release];
}
Is this code okay, or should I edit something?

The docs recommend using [[UIScreen mainScreen] applicationFrame] to get the screen bounds without the status bar

so for anyone who want to know a best practice example:
#pragma mark -
#pragma mark LoadView Methods
- (void)loadView {
//Calculate Screensize
BOOL statusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden ];
BOOL navigationBarHidden = [self.navigationController isNavigationBarHidden];
BOOL tabBarHidden = [self.tabBarController.tabBar isHidden];
BOOL toolBarHidden = [self.navigationController isToolbarHidden];
CGRect frame = [[UIScreen mainScreen] applicationFrame];
//check if you should rotate the view, e.g. change width and height of the frame
BOOL rotate = NO;
if ( UIInterfaceOrientationIsLandscape( [UIApplication sharedApplication].statusBarOrientation ) ) {
if (frame.size.width < frame.size.height) {
rotate = YES;
}
}
if ( UIInterfaceOrientationIsPortrait( [UIApplication sharedApplication].statusBarOrientation ) ) {
if (frame.size.width > frame.size.height) {
rotate = YES;
}
}
if (rotate) {
CGFloat tmp = frame.size.height;
frame.size.height = frame.size.width;
frame.size.width = tmp;
}
if (statusBarHidden) {
frame.size.height -= [[UIApplication sharedApplication] statusBarFrame].size.height;
}
if (!navigationBarHidden) {
frame.size.height -= self.navigationController.navigationBar.frame.size.height;
}
if (!tabBarHidden) {
frame.size.height -= self.tabBarController.tabBar.frame.size.height;
}
if (!toolBarHidden) {
frame.size.height -= self.navigationController.toolbar.frame.size.height;
}
UIView *v = [[UIView alloc] initWithFrame: frame];
v.backgroundColor = [UIColor whiteColor];
v.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view = v;
[v release]; //depends on your ARC configuration
}

You are adjusting the height depend on the status bar and navigation bars.. But you have not done anything with respect to the origin of the view.

Related

Resign first responder doesn't work when picker is show

I've a problem with date picker. When I touch on textfield(datumletu) I call picker and datumletu [resign firstresponder]. But no effect.
Here is my code. I'm trying everything but nothing is working.
-(void)textFieldDidBeginEditing:(UITextField *)textField {
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
if (textField == self.datumLetu) {
[self.view endEditing:YES];
[self.autoTextFieldPriletu resignFirstResponder];
[self.autoTextField resignFirstResponder];
[self.cisloLetu resignFirstResponder];
[self.datumLetu resignFirstResponder];
self.picker.hidden = YES;
[self showPicker];
CGRect rect = self.view.frame;
if(rect.origin.y == 0)
{
rect.origin.y -= 110;
rect.size.height += 110;
[UIView animateWithDuration:0.2 animations:^{
self.view.frame = rect;
}];
self.picker.frame = CGRectMake(0, screenHeight / 2 + screenHeight / 3.2, screenWidth, screenHeight/2);
}
and picker
-(void)showPicker
{
[self showAction];
}
-(void) showAction
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
self.picker = [[Picker alloc] initWithFrame:CGRectMake(0, screenHeight / 2 + screenHeight / 10.5, screenWidth, screenHeight/2)];
[self.picker addTargetForDoneButton:self action:#selector(cancelPressed)];
[self.picker addTargetForCancelButton:self action:#selector(cancelPressed)];
[self.picker setMode:UIDatePickerModeDateAndTime];
[self.picker.picker addTarget:self action:#selector(pickerChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:self.picker];
self.picker.hidden = NO;
}
Any help is highly appreciated.
In your ViewController add the delegate of the UITextField :
#interface ViewController : UIViewController <UITextFieldDelegate>
While Creating the UITextField or in ViewDidLoad:
self.myTextField.delegate = self;
In your implementation file:
#pragma mark - UITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
// show your picker here
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}

image view not scrollable in scrollview and not fit properly using pure layout

I'm simply trying to place an image into scroll view which is in a main view using purelayout.
And what i'm taking right now is;
Note that view with red background is scroll view. And also the image is not scrollable.
- (void)loadView {
self.view = [[UIView alloc] init];
[self.scrollView addSubview:self.photoView];
[self.view addSubview:self.scrollView];
[self.view setNeedsUpdateConstraints];
}
- (void)updateViewConstraints {
if (!_didSetupConstraints) {
...
...
...
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeRight];
self.didSetupConstraints = YES;
}
[super updateViewConstraints];
}
- (UIImageView *)photoView {
if (!_photoView) {
_photoView = [UIImageView newAutoLayoutView];
_photoView.backgroundColor = [UIColor whiteColor];
}
return _photoView;
}
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [UIScrollView newAutoLayoutView];
_scrollView.backgroundColor = [UIColor redColor];
_scrollView.maximumZoomScale = 2.0;
_scrollView.minimumZoomScale = 0.5;
}
return _scrollView;
}
Ok, it seems working well with two changes i did.
Firstly i set self.photoView size manually.
[self.photoView autoSetDimensionsToSize:CGSizeMake([HelperModel screenWidth], [HelperModel screenHeight] -[HelperModel viewHeight:self.navigationController.navigationBar] -20.0)];
HelperModel.m
#implementation HelperModel
+ (CGFloat)screenWidth {
return [[UIScreen mainScreen] bounds].size.width;
}
+ (CGFloat)screenHeight {
return [[UIScreen mainScreen] bounds].size.height;
}
+ (CGFloat)viewHeight:(UIView *)view {
return CGRectGetHeight(view.frame);
}
+ (CGFloat)photoDetailHeight {
return [HelperModel screenHeight] -20;
}
#end
Secondly,
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
for zooming feature and if the zoomed image exceeds the bounds of scroll view, then the image can be scrolled properly.

ActionsheetPicker is blank

I have ActionSheetPicker working in a test project, but when I try and paste the same code into my existing project I see this:
I'm the sample code from their example page verbatim:
NSArray *colors = [NSArray arrayWithObjects:#"Red", #"Green", #"Blue", #"Orange", nil];
[ActionSheetStringPicker showPickerWithTitle:#"Select a Color"
rows:colors
initialSelection:0
doneBlock:nil
cancelBlock:nil
origin:sender];
Any ideas?
Actually there is problem with iOS 8 .same code will work in iOS 7 from here after
UIActionSheet is not designed to be subclassed, nor should you add views to its hierarchy. If you need to present a sheet with more customization than provided by the UIActionSheet API, you can create your own and present it modally with presentViewController:animated:completion:
UIActionSheet is not designed to be subclassed. Create your own action sheet.
File : CustomActionSheet.h
//
// CustomActionSheet.h
// CustomActionSheet
//
// Created by Ramesh Annadurai on 09/07/14.
// Copyright (c) 2014 Slingshots. All rights reserved.
//
#define SYSTEM_VERSION_LESS_THAN(version) ([[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] == NSOrderedAscending)
#import <UIKit/UIKit.h>
#import "CustomActionSheetDelegate.h"
#interface CustomActionSheet : UIView
#property (strong, nonatomic) id<CustomActionSheetDelegate> delegate;
- (id) init;
- (void) addContentView:(UIView *) contentView;
- (void) showInView:(UIView *) theView;
- (void) rotateToCurrentOrientation;
#end
File : CustomActionSheet.m
//
// CustomActionSheet.m
// CustomActionSheet
//
// Created by Ramesh Annadurai on 09/07/14.
// Copyright (c) 2014 Slingshots. All rights reserved.
//
#import "CustomActionSheet.h"
#interface CustomActionSheet ()
#property (readonly) UIView *transparentView;
#property (readonly) UIToolbar *toolBar;
#property (readonly) UIBarButtonItem *flexBarButtonItem, *doneBarButtonItem;
#property (strong, nonatomic) UIView *mContentView;
#property BOOL shouldCancelOnTouch, visible;
#end
#implementation CustomActionSheet
#synthesize transparentView = _transparentView, toolBar = _toolBar, flexBarButtonItem = _flexBarButtonItem, doneBarButtonItem = _doneBarButtonItem;
- (id) init
{
self = [super initWithFrame:CGRectMake(0, 0, CGRectGetWidth([[UIScreen mainScreen] bounds]), 0)];
if (self) {
self.shouldCancelOnTouch = YES;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissActionSheet)];
[singleTap setNumberOfTapsRequired:1];
[self.transparentView addGestureRecognizer:singleTap];
[self setBackgroundColor:[UIColor whiteColor]];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void) addContentView:(UIView *)contentView
{
[self.toolBar setItems:#[self.flexBarButtonItem, self.doneBarButtonItem]];
[self addSubview:self.toolBar];
if (contentView) {
float width;
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect screenRect = [[UIScreen mainScreen] bounds];
if (UIInterfaceOrientationIsPortrait(statusBarOrientation)) {
width = CGRectGetWidth(screenRect);
} else {
width = CGRectGetHeight(screenRect);
}
self.mContentView = contentView;
[self.mContentView setFrame:CGRectMake(0, CGRectGetHeight(self.toolBar.frame), width, CGRectGetHeight(self.mContentView.frame))];
NSLog(#"tool bar height : %f", CGRectGetHeight(self.toolBar.frame));
[self.mContentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self addSubview:self.mContentView];
self.shouldCancelOnTouch = NO;
}
}
- (void) showInView:(UIView *)theView
{
/*
* 1. Add the view (self) as sub view of the parent (theView) view.
* 2. Insert the transparent view to disable the parent view from the user intraction.
*/
[theView addSubview:self];
[theView insertSubview:self.transparentView belowSubview:self];
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect screenRect = [[UIScreen mainScreen] bounds];
float width, height, x;
width = height = x = 0;
if (UIInterfaceOrientationIsPortrait(statusBarOrientation)) {
width = CGRectGetWidth(screenRect);
height = CGRectGetHeight(screenRect);
} else {
width = CGRectGetHeight(screenRect);
height = CGRectGetWidth(screenRect);
}
[self.transparentView setFrame:CGRectMake(0, 0, width, height)];
[self.transparentView setCenter:CGPointMake(width / 2.0, height / 2.0)];
[self setCenter:CGPointMake(width / 2.0, height - CGRectGetHeight(self.frame) / 2.0)];
if (SYSTEM_VERSION_LESS_THAN(#"7.0")) {
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^() {
[self.transparentView setAlpha:0.4f];
[self setCenter:CGPointMake(width / 2.0, (height - 20) - CGRectGetHeight(self.frame) / 2.0)];
[self setFrame:CGRectMake(0, 0, width, CGRectGetHeight(self.mContentView.frame) + CGRectGetHeight(self.toolBar.frame))]; // height -> content view height + toolbar height
} completion:^(BOOL finished) {
self.visible = YES;
}];
} else {
[UIView animateWithDuration:0.5f
delay:0
usingSpringWithDamping:0.6f
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
[self.transparentView setAlpha:0.4f];
[self setCenter:CGPointMake(width / 2.0, height - CGRectGetHeight(self.frame) / 2.0)];
[self setFrame:CGRectMake(0, 0, width, CGRectGetHeight(self.mContentView.frame) + CGRectGetHeight(self.toolBar.frame))]; // height -> content view height + toolbar height
} completion:^(BOOL finished) {
self.visible = YES;
}];
}
}
- (void) removeFromView {
if (self.shouldCancelOnTouch) {
if (SYSTEM_VERSION_LESS_THAN(#"7.0")) {
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^() {
[self.transparentView setAlpha:0.0f];
self.center = CGPointMake(CGRectGetWidth(self.frame) / 2.0, CGRectGetHeight([UIScreen mainScreen].bounds) + CGRectGetHeight(self.frame) / 2.0);
} completion:^(BOOL finished) {
[self.transparentView removeFromSuperview];
[self removeFromSuperview];
self.visible = NO;
}];
} else {
[UIView animateWithDuration:0.5f
delay:0
usingSpringWithDamping:0.6f
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
[self.transparentView setAlpha:0.0f];
self.center = CGPointMake(CGRectGetWidth(self.frame) / 2.0, CGRectGetHeight([UIScreen mainScreen].bounds) + CGRectGetHeight(self.frame) / 2.0);
} completion:^(BOOL finished) {
[self.transparentView removeFromSuperview];
[self removeFromSuperview];
self.visible = NO;
}];
}
}
}
-(void) dismissActionSheet
{
[self removeFromView];
}
#pragma mark - UI Elements
- (UIView *) transparentView
{
if (!_transparentView) {
_transparentView = [UIView new];
[_transparentView setBackgroundColor:[UIColor blackColor]];
[_transparentView setAlpha:0.0f];
}
return _transparentView;
}
- (UIToolbar *)toolBar
{
if (!_toolBar) {
_toolBar = [UIToolbar new];
[_toolBar setBarStyle:UIBarStyleBlack];
[_toolBar setTranslucent:YES];
[_toolBar setTintColor:nil];
[_toolBar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[_toolBar sizeToFit];
}
return _toolBar;
}
- (UIBarButtonItem *) flexBarButtonItem
{
if (!_flexBarButtonItem) {
_flexBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
}
return _flexBarButtonItem;
}
- (UIBarButtonItem *) doneBarButtonItem
{
if (!_doneBarButtonItem) {
_doneBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonAction:)];
}
return _doneBarButtonItem;
}
#pragma mark - Auto Layout Constraints
#pragma mark - Button Action Methods
- (void) doneButtonAction:(id) sender
{
self.shouldCancelOnTouch = YES;
[self dismissActionSheet];
if ([self.delegate respondsToSelector:#selector(CustomActionSheetDoneWithUserInfo:)]) {
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setValue:self forKey:#"actionSheet"];
[self.delegate performSelector:#selector(CustomActionSheetDoneWithUserInfo:) withObject:userInfo];
}
}
#pragma mark - Gesture Recognizer
#pragma mark - Other Methods
-(void) rotateToCurrentOrientation
{
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect screenRect = [[UIScreen mainScreen] bounds];
float width, height, x;
width = height = x = 0;
if (UIInterfaceOrientationIsPortrait(statusBarOrientation)) {
width = CGRectGetWidth(screenRect);
height = CGRectGetHeight(screenRect);
} else {
width = CGRectGetHeight(screenRect);
height = CGRectGetWidth(screenRect);
}
[self.transparentView setFrame:CGRectMake(0, 0, width, height)];
[self.transparentView setCenter:CGPointMake(width / 2.0, height / 2.0)];
if (SYSTEM_VERSION_LESS_THAN(#"7.0")) {
[self setFrame:CGRectMake(0, 0, width, CGRectGetHeight(self.mContentView.frame) + CGRectGetHeight(self.toolBar.frame))]; // height -> content view height + toolbar height
[self setCenter:CGPointMake(width / 2.0, (height - 20) - CGRectGetHeight(self.frame) / 2.0)];
} else {
[self setFrame:CGRectMake(0, 0, width, CGRectGetHeight(self.mContentView.frame) + CGRectGetHeight(self.toolBar.frame))]; // height -> content view height + toolbar height
[self setCenter:CGPointMake(width / 2.0, height - CGRectGetHeight(self.frame) / 2.0)];
}
//[self.mContentView setFrame:CGRectMake(0, CGRectGetHeight(self.toolBar.frame), width, CGRectGetHeight(self.mContentView.frame))];
[self.toolBar setFrame:CGRectMake(0, 0, width, 44)];
}
#pragma mark - Drawing Methods
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
File : CustomActionSheetDelegate.h
//
// CustomActionSheetDelegate.h
// CustomActionSheetDelegate
//
// Created by Ramesh Annadurai on 10/07/14.
// Copyright (c) 2014 Slingshots. All rights reserved.
//
#import <Foundation/Foundation.h>
#protocol CustomActionSheetDelegate <NSObject>
#optional
- (void) CustomActionSheetDoneWithUserInfo:(NSDictionary *) userInfo;
#end
Finally use this Custom Action Sheet in your view controller (ie. in your button action). Add your picker view as subview of innerView
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect screenRect = [[UIScreen mainScreen] bounds];
float width = 0;
if (UIInterfaceOrientationIsPortrait(statusBarOrientation)) {
width = CGRectGetWidth(screenRect);
} else {
width = CGRectGetHeight(screenRect);
}
CustomActionSheet *actionSheet = [[CustomActionSheet alloc] init];
UIView *innerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 216)];
[innerView setBackgroundColor:[UIColor greenColor]];
[innerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[actionSheet setDelegate:self];
[actionSheet addContentView:innerView];
[innerView addSubview:self.colorsPickerView]; // Added your picker view here
[self.actionSheet showInView:self.view];
Add delegate method to view controller. While closing the action sheet the below delegate method will be called.
- (void) CustomActionSheetDoneWithUserInfo:(NSDictionary *)userInfo
{
NSLog(#"i am in delegate method of CustomAction sheet");
}
Customize the above code as per your requirement.
It's a bit silly, but I was using an outdated version of ActionSheetPicker. You want to be sure you download the branch from https://github.com/skywinder/ActionSheetPicker-3.0 .

JTRevealSideBar UI is not getting displayed properly in landscape mode on iPhone and iPad

In my project I am using JTRevealSideBar to show side table UI, but when I am changing iPad/iPhone from portrait to landscape mode the UI iss getting disturbed
http://screencast.com/t/EDi8xbsvV
- (CGRect)applicationViewFrame {
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
CGRect expectedFrame = [self.view convertRect:appFrame fromView:nil];
return expectedFrame;
}
- (UIView *)viewForLeftSidebar {
CGRect mainFrame = [self.navigationController applicationViewFrame];
if (!self.leftSidebarViewController) {
SP2SideBarViewController * sideController = [[SP2SideBarViewController alloc] initWithStyle:UITableViewStylePlain];
self.leftSidebarViewController = sideController;
[sideController release];
self.leftSidebarViewController.sidebarDelegate = self;
if ( self.callerAppName )
[self.leftSidebarViewController setLaunchAppName:self.callerAppName];
if ([UIHelper isPad]) {
self.leftSidebarViewController.view.frame = CGRectMake(0, mainFrame.origin.y, SIDEBAR_IPAD_WIDTH, mainFrame.size.height);
} else {
self.leftSidebarViewController.view.frame = CGRectMake(0, mainFrame.origin.y, 170, mainFrame.size.height);
}
self.leftSidebarViewController.title = #"LeftSidebarViewController";
self.leftSidebarViewController.view.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
}
self.leftSidebarViewController.slideDecksCount = [slideDecks count];
self.leftSidebarViewController.jsonDecksCount = [self.jsonDecks count];
// [self.leftSidebarViewController.tableView reloadData];
return self.leftSidebarViewController.view;
}
Thanks in advance
Try this for side menu apps its working fine in ios6,ios7.
https://github.com/mikefrederick/MFSideMenu

Second ScrollView doesn't zoom or scroll

I have two Scroll View's in a xib, and they both contain a very large image that should start with it completely scaled down to fit. The first ScrollView works perfectly, objects are all moving around correctly when you zoom or scroll, but the second ScrollView starts completely zoomed in, unable to zoom out.
The ScrollView is now showing 25% of the image(completely zoomed in at 0,0) and also cannot be dragged to see the rest. If I pinch to zoom, the image moves diagonally up and left without zooming at all, I can now drag the image back to 0,0 and back down the the max point it scrolled diagonally.
.h file
UIScrollView *_scrollView;
UIScrollView *_miamiScrollView;
UIView *_mapImageView;
UIView *_mapMiamiView;
UIView *_mapContentView;
NSArray *_autoLayoutViews;
NSArray *_staticViews;
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;//(linked to working scrollview)
#property (strong, nonatomic) IBOutlet UIScrollView *miamiScrollView;//(Linked to 'broken' scrollview)
.m file
- (void)viewDidLoad
{
[self _customizeViews];
}
- (void) _customizeViews
{
UIImageView *mapImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MainGameDisplay.jpg"]];
mapImageView.userInteractionEnabled = YES;
UIImageView *mapMiamiView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"miami.jpg"]];
mapMiamiView.userInteractionEnabled = YES;
_mapContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 568, 270)];
_mapContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_mapContentView.clipsToBounds = YES;
_mapContentView.userInteractionEnabled = YES;
[_mapContentView addSubview:_scrollView];
[_mapContentView addSubview:_miamiScrollView];
[self.view addSubview:_mapContentView];
[self.view sendSubviewToBack:_mapContentView];
UIScrollView *scrollView = _scrollView;
CGRect scrollFrame = scrollView.frame;
scrollFrame.origin = CGPointZero;
scrollView.frame = scrollFrame;
scrollView.delegate = self;
scrollView.minimumZoomScale = 1;
scrollView.maximumZoomScale = 1.0;
[scrollView addSubview:mapImageView];
scrollView.contentSize = mapImageView.frame.size;
_scrollView = scrollView;
_mapImageView = mapImageView;
UIScrollView *miamiScrollView = _miamiScrollView;
CGRect miamiScrollFrame = CGRectMake(0 , 270, 568, 270);
scrollFrame.origin = CGPointZero;
miamiScrollView.frame = miamiScrollFrame;
miamiScrollView.delegate = self;
miamiScrollView.minimumZoomScale = 0.125;
miamiScrollView.maximumZoomScale = 1;
[miamiScrollView addSubview:mapMiamiView];
miamiScrollView.contentSize = mapMiamiView.frame.size;
_miamiScrollView = miamiScrollView;
_mapMiamiView = mapMiamiView;
[self _setupAutolayoutViews];
[self _setupStaticViews];
[self _zoomToFit: _scrollView];
[self _zoomToFit: _miamiScrollView];
[self _updatePositionForViews:_autoLayoutViews];
}
- (void) _zoomToFit: (UIScrollView*)view
{
CGFloat contentWidth = view.contentSize.width;
CGFloat contentHeigth = view.contentSize.height;
CGFloat viewWidth = view.frame.size.width;
CGFloat viewHeight = view.frame.size.height;
CGFloat width = viewWidth / contentWidth;
CGFloat heigth = viewHeight / contentHeigth;
CGFloat scale = MAX(width, heigth);
if ( scale < view.minimumZoomScale ) {
view.minimumZoomScale = scale;
} else if ( scale > view.maximumZoomScale ) {
view.maximumZoomScale = scale;
}
view.zoomScale = scale;
}
#pragma mark - Positions
- (void) _updatePositionForViews:(NSArray *)views
{
CGFloat scale = _scrollView.zoomScale;
CGPoint contentOffset = _scrollView.contentOffset;
contentOffset.x -= _scrollView.frame.origin.x;
contentOffset.y -= _scrollView.frame.origin.y;
for ( UIView *view in views ) {
CGPoint basePosition = [self _basePositionForView:view];
[self _updatePositionForView:view scale:scale basePosition:basePosition offset:contentOffset];
}
}
- (CGPoint) _basePositionForView:(UIView *)view
{
NSString *key = [NSString stringWithFormat:#"%d", view.tag];
NSString *stringValue = [_coordinates objectForKey:key];
NSArray *values = [stringValue componentsSeparatedByString:#":"];
if ( [values count] < 2 ) return CGPointZero;
CGPoint result = CGPointMake([[values objectAtIndex:0] floatValue], [[values objectAtIndex:1] floatValue]);
return result;
}
- (void) _updatePositionForView:(UIView *)view scale:(CGFloat)scale basePosition:(CGPoint)basePosition offset:(CGPoint)offset;
{
CGPoint position;
position.x = (basePosition.x * scale) - offset.x;
position.y = (basePosition.y * scale) - offset.y;
CGRect frame = view.frame;
frame.origin = position;
view.frame = frame;
}
//////////////////////////////////////////////////////////////////////////////////////
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{
[self _lockInteraction];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
[self _unlockInteraction];
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
[self _lockInteraction];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
[self _unlockInteraction];
}
- (void) _lockInteraction
{
[self _setControls:_staticViews interacted:NO];
[self _setControls:_autoLayoutViews interacted:NO];
}
- (void) _unlockInteraction
{
[self _setControls:_staticViews interacted:YES];
[self _setControls:_autoLayoutViews interacted:YES];
}
- (void) _setControls:(NSArray *)controls interacted:(BOOL)interacted
{
for ( UIControl *control in controls ) {
if ( [control isKindOfClass:[UIControl class]]) {
control.userInteractionEnabled = interacted;
}
}
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
[self _updatePositionForViews:_autoLayoutViews];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self _updatePositionForViews:_autoLayoutViews];
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView;
{
return _mapImageView;
}
//DEFAULT BUTTONS.
- (void) _setupAutolayoutViews
{
UIButton *btn1 = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
[btn1 addTarget:self action:#selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
btn1.tag = kAddContactButton;
btn1.center = CGPointZero;
[_mapContentView addSubview:btn1];
_autoLayoutViews = [[NSArray alloc] initWithObjects:btn1, nil];
}
//CUSTOM BUTTONS.
- (void) _setupStaticViews
{
UIButton *openMiamiButton = [UIButton buttonWithType:UIButtonTypeCustom];
[openMiamiButton setBackgroundImage:[UIImage imageNamed:#"logo.png"] forState:UIControlStateNormal];
[openMiamiButton addTarget:self action:#selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
openMiamiButton.frame = CGRectMake(0.0 ,0.0, 50.0, 50.0);
openMiamiButton.tag = OpenMiamiButton;
openMiamiButton.enabled = YES;
openMiamiButton.alpha = 0.5;
[_mapImageView addSubview:openMiamiButton];
_staticViews = #[openMiamiButton,];
for ( UIView *view in _staticViews ) {
CGPoint point = [self _basePositionForView:view];
CGRect frame = view.frame;
frame.origin = point;
view.frame = frame;
}
}
//And for the transition between views:
-(void) quickTest: (UIButton *)button
{
/*
if (!openMiami)
openMiami = [[MiamiGameDisplay alloc] initWithNibName:nil bundle:nil];
openMiami.mainPage = self;
[self.navigationController pushViewController:openMiami animated:YES];
*/
if (!testBool){
[UIView animateWithDuration:0.5f
animations:^{
_scrollView.frame = CGRectMake(0 , -270, 568, 270);
}
completion:Nil];
[UIView animateWithDuration:0.5f
animations:^{
_miamiScrollView.frame = CGRectMake(0 , 0, 568, 270);
}
completion:Nil];
testBool=YES;
}
else {
[UIView animateWithDuration:0.5f
animations:^{
_miamiScrollView.frame = CGRectMake(0 , 270, 568, 270);
}
completion:Nil];
[UIView animateWithDuration:0.5f
animations:^{
_scrollView.frame = CGRectMake(0 , 0, 568, 270);
}
completion:Nil];
testBool=NO;
}
}
I've run into a similar issue with scrollViews. Basically, as far as I can tell, only the last scrollView added to the window will respond as a scrollView.
You can produce the same effect with any other type of object being added to the window before the scrollView.
Example :
[[self window] addSubview:logo];
[[self window] addSubview:scrollView];
Will work, but:
[[self window] addSubview:scrollView];
[[self window] addSubview:logo];
will not. (Currently running against iOS 6.1.2 and xCode 4.6.1)

Resources