in my iOS application, I am adding functionality for collapsing toolbar when table view scrolls. But when toolbar moves above along y axis, I got following result (toolbar contents mixing with status bar contents).
#interface ListViewController () <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UILabel *labelPageTitle;
#property (weak, nonatomic) IBOutlet UITableView *listTableView;
#property (nonatomic) CGFloat previousScrollViewYOffset;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *toolbarTop;
#end
#implementation ListViewController
//- (void)scrollViewDidScroll:(UIScrollView *)scrollView
//{
// CGRect frame = self.toolbars.frame;
// CGFloat size = frame.size.height - 21;
// CGFloat framePercentageHidden = ((20 - frame.origin.y) / (frame.size.height - 1));
// CGFloat scrollOffset = scrollView.contentOffset.y;
// CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset;
// CGFloat scrollHeight = scrollView.frame.size.height;
//
// NSLog(#"scrollView.frame - %#", NSStringFromCGRect(scrollView.frame));
// NSLog(#"scrollView.contentInset - %#", NSStringFromUIEdgeInsets(scrollView.contentInset));
//
// CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;
//
// if (scrollOffset <= -scrollView.contentInset.top) {
// frame.origin.y = 20;
// } else if ((scrollOffset + scrollHeight) >= scrollContentSizeHeight) {
// frame.origin.y = -size;
// } else {
// frame.origin.y = MIN(20, MAX(-size, frame.origin.y - scrollDiff));
// }
//
// [self.toolbars setFrame:frame];
// [self updateBarButtonItems:(1 - framePercentageHidden)];
// self.previousScrollViewYOffset = scrollOffset;
//}
//
//- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
//{
// [self stoppedScrolling];
//}
//
//- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
// willDecelerate:(BOOL)decelerate
//{
// if (!decelerate) {
// [self stoppedScrolling];
// }
//}
//
//- (void)stoppedScrolling
//{
// CGRect frame = self.navigationController.navigationBar.frame;
// if (frame.origin.y < 20) {
// [self animateNavBarTo:-(frame.size.height - 21)];
// }
//}
//
//- (void)updateBarButtonItems:(CGFloat)alpha
//{
// self.buttonDismiss.customView.alpha = alpha;
// self.labelPageTitle.alpha = alpha;
// self.toolbars.tintColor = [self.toolbars.tintColor colorWithAlphaComponent:alpha];
//}
//
//- (void)animateNavBarTo:(CGFloat)y
//{
// [UIView animateWithDuration:0.2 animations:^{
// CGRect frame = self.toolbars.frame;
// CGFloat alpha = (frame.origin.y >= y ? 0 : 1);
// frame.origin.y = y;
// [self.toolbars setFrame:frame];
// [self updateBarButtonItems:alpha];
// }];
//}
#pragma mark - view controllers life cycle methods
- (void)viewDidLoad {
[super viewDidLoad];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;
[self.view layoutIfNeeded];
_toolbarTop.constant = -34;
[self.listTableView setDataSource:self];
[self.listTableView setDelegate:self];
[Utils updateLabelFontSize:self.labelPageTitle ForInitialHeight:22 andInitialSize:21];
[self.labelPageTitle setText:#"My Category"/*self.productCategory*/];
}
Finally after playing for 4-5 hours, I come across the solution. First of all thanks to #Lion & #Desdenova for help.
Here is the link where I found some hint.
iOS8: How do I make statusBar opaque after navigationBar is hidden using hidesBarsOnSwipe?
as per suggestions in the post I just assigned one UIView at status bar frame with same color of toolbar tint.
Here is my updated code in view did load. Remaining is the same
- (void)viewDidLoad {
[super viewDidLoad];
// if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
// self.edgesForExtendedLayout = UIRectEdgeNone;
//
// self.extendedLayoutIncludesOpaqueBars=NO;
// self.automaticallyAdjustsScrollViewInsets=NO;
[self.view layoutIfNeeded];
_toolbarTop.constant = -34;
[self.listTableView setDataSource:self];
[self.listTableView setDelegate:self];
//let topBar = UIView(frame: UIApplication.sharedApplication().statusBarFrame)
UIView *statusBarView = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] statusBarFrame]];
statusBarView.backgroundColor = self.view.backgroundColor;
[self.view addSubview:statusBarView];
[Utils updateLabelFontSize:self.labelPageTitle ForInitialHeight:22 andInitialSize:21];
[self.labelPageTitle setText:#"My Category"/*self.productCategory*/];
}
Final Result
Do not pin constraint from TopLayoutGuide.Bottom, instead pin it with superview's top. You your toolbar's top should be pinned with superview's top. Check the below screenshot,
Related
I placed a scrollview in storyboard ,i enabled paging also ,i made outlet for scrollview, i added 4 uiviews programmatically.Now i need paging with that 4 uiview in horizontally .Please help me to do ...
Thanks in advance
Here is my code
- (void)scrollingView
{
UIView *pageView1 = [[UIView alloc]init];
pageView1.frame = CGRectMake(0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
pageView1.backgroundColor = [UIColor blueColor];
[self.scrollView addSubview:pageView1];
UIView *pageView2 = [[UIView alloc]init];
pageview2.frame = CGRectMake(0,0,self.scrollView.frame.size,width,self.scrollView.frame.size.height);
pageView2.backgroundColor =[UIColor GrayColor];
[self.scrollView addSubview:pageView2];
}
xPosition = 0;
for (int i = 0; i<3; i++)
{
scrollView.clipsToBounds = YES;
//Views
UIView *views = [[UIView alloc]initWithFrame:CGRectMake(xPosition, 0, selfView.frame.size.width, scrollView.frame.size.height)];
views.clipsToBounds = YES;
[arrayOfViews addObject:views];
xPosition += selfView.frame.size.width;
[scrollView addSubview:views];
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayOfViews.count, scrollView.frame.size.height);
and implement scrollview delegate method
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageCnt.currentPage = page;
}
-(void)viewDidLayoutSubviews
{
UIImage *image1=[UIImage imageNamed:#"1.jpeg"];
UIImage *image2=[UIImage imageNamed:#"2.jpeg"];
UIImage *image3=[UIImage imageNamed:#"7.jpeg"];
UIImage *image4=[UIImage imageNamed:#"6.jpeg"];
// UIImage *image5=[[UIImage alloc]init];
NSArray *imagesArray=[[NSArray alloc]initWithObjects:image1,image2,image3,image4,nil];
for (int i=0; i<=3; i++) {
UIImageView *imgView=[[UIImageView alloc]init];
imgView.backgroundColor=[UIColor grayColor];
imgView.contentMode=UIViewContentModeScaleToFill;
imgView.alpha=0.5f;
imgView.frame=CGRectMake(i*self.scrollViewSlider.bounds.size.width, 0, self.scrollViewSlider.bounds.size.width, self.scrollViewSlider.bounds.size.height);
[imgView setImage:imagesArray[i]];
[self.scrollViewSlider addSubview:imgView];
}
self.scrollViewSlider.pagingEnabled=TRUE;
[self.scrollViewSlider setContentSize:CGSizeMake(imagesArray.count * self.scrollViewSlider.bounds.size.width, self.scrollViewSlider.bounds.size.height)];
}
- (void) scrollViewDidEndDecelerating: (UIScrollView *) __unused scrollView
{
CGFloat pageWidth = self.scView.frame.size.width;
self.pageControl.currentPage = (self.scView.contentOffset.x + pageWidth / 2) / pageWidth;
}
Try this u will get it is working
Header file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
#property (weak, nonatomic) IBOutlet UIScrollView *scView;
#end
Implementation :
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidLayoutSubviews
{
NSArray *imagesArray=[NSArray arrayWithObjects:
[UIColor colorWithRed:246/255.0 green:155/255.0 blue:0/255.0 alpha:1],
[UIColor colorWithRed:129/255.0 green:195/255.0 blue:29/255.0 alpha:1],
[UIColor colorWithRed:62/255.0 green:173/255.0 blue:219/255.0 alpha:1],
[UIColor colorWithRed:229/255.0 green:66/255.0 blue:115/255.0 alpha:1],
[UIColor colorWithRed:148/255.0 green:141/255.0 blue:139/255.0 alpha:1],nil];
for (int i=0; i<imagesArray.count; i++) {
UIView *containerView=[[UIView alloc]init ];
//containerView.backgroundColor=[UIColor redColor]
containerView.backgroundColor=imagesArray[i % imagesArray.count];
containerView.contentMode=UIViewContentModeScaleToFill;
containerView.alpha=0.5f;
containerView.frame=CGRectMake(i*self.scView.bounds.size.width, 0, self.scView.bounds.size.width, self.scView.bounds.size.height);
//[imgView setImage:imagesArray[i]];
[self.scView addSubview:containerView];
}
self.scView.pagingEnabled=TRUE;
NSLog(#"%ld",imagesArray.count);
NSLog(#"%ld",imagesArray.count);
[self.scView setContentSize:CGSizeMake(imagesArray.count * self.scView.bounds.size.width, self.scView.bounds.size.height)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) scrollViewDidEndDecelerating: (UIScrollView *) __unused scrollView
{
CGFloat pageWidth = self.scView.frame.size.width;
self.pageControl.currentPage = (self.scView.contentOffset.x + pageWidth / 2) / pageWidth;
NSLog(#"%f",pageWidth);
}
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 .
I've edited this question a few times, but can still not get my images to center inside a uiview. I want them to be able to rotate like the photos app and display the correct size when a user brings them up. Here is what I'm working with:
In my PhotoViewController.h
#import <UIKit/UIKit.h>
#protocol PhotoViewControllerDelegate <NSObject>
- (void)toggleChromeDisplay;
#end
#interface PhotoViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
#property (nonatomic, strong) UIImage *photo;
#property (nonatomic) NSUInteger num;
//Delegate
#property (nonatomic, strong) id<PhotoViewControllerDelegate> photoViewControllerDelegate;
#property (nonatomic, strong) UIImageView *photoImgView;
#property (nonatomic, strong) UIScrollView *scrollView;
#end
In my PhotoViewController.m:
#import "PhotoViewController.h"
#interface PhotoViewController ()
#end
#implementation PhotoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//todo
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect screenBounds = self.view.bounds;
//scroll view
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height)];
_scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
_scrollView.pagingEnabled = NO;
_scrollView.scrollEnabled = YES;
[_scrollView setBackgroundColor:[UIColor blueColor]];
//Zoom Properties
_scrollView.maximumZoomScale = 6.0;
_scrollView.minimumZoomScale = 1.0;
_scrollView.bouncesZoom = YES;
_scrollView.delegate = self;
_scrollView.zoomScale = 1.0;
_scrollView.contentSize = _photoImgView.bounds.size;
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
[self photoBounds];
[self.view addSubview: _scrollView];
//Add the UIImageView
_photoImgView = [[UIImageView alloc] initWithImage:_photo];
_photoImgView.image = _photo;
_photoImgView.clipsToBounds = YES;
_photoImgView.contentMode = UIViewContentModeScaleAspectFit;
_photoImgView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin);
[_photoImgView setUserInteractionEnabled:YES];
[_scrollView addSubview: _photoImgView];
//Set up Gesture Recognizer
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
UITapGestureRecognizer *dTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dTapGestureCaptured:)];
dTap.numberOfTapsRequired = 2;
[singleTap requireGestureRecognizerToFail:dTap];
//Gesture Methods
[self.scrollView addGestureRecognizer:singleTap];
[self.scrollView addGestureRecognizer : dTap];
}
- (void)photoBounds
{
UIInterfaceOrientation statusbar = [[UIApplication sharedApplication] statusBarOrientation];
CGSize photoBounds = _photo.size;
CGSize scrollBounds = self.view.bounds.size;
CGRect frameToCenter = [_photoImgView frame];
float newHeight = (scrollBounds.width / photoBounds.width) * photoBounds.height;
float newWidth = (scrollBounds.height / photoBounds.height) * photoBounds.width;
float yDist = fabsf(scrollBounds.height - newHeight) / 2;
float xDist = fabsf(scrollBounds.width - newWidth) / 2;
//Width Larger
if (photoBounds.width >=photoBounds.height) {
NSLog(#"portrait width");
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
}
//Height Larger
else if (photoBounds.height > photoBounds.width) {
NSLog(#"portrait height");
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
//Square
else {
NSLog(#"portrait square");
if ((statusbar == 1) || (statusbar == 2)) {
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
} else {
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
}
}
//Rotation Magic
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//later
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self photoBounds];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
//Zoom Ability
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.photoImgView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
NSLog(#"scale %f", scale);
NSLog(#"done zooming");
}
//Touches Control
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
//CGPoint touchPoint=[gesture locationInView:_scrollView];
NSLog(#"touched");
NSLog(#"single touch");
[self performSelector:#selector(callingHome) withObject:nil afterDelay:0];
}
- (void)dTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
NSLog(#"double touched");
}
- (void)panGestureCaptured:(UIPanGestureRecognizer *)gesture
{
NSLog(#"pan gesture");
}
- (void)callingHome {}
#end
The overall issue is that I can not get my picture to display correctly and be able to zoom on just it, no space around it and It needs to be the correct dimensions on load. I've been struggling with it for a few days.
Any help?
I have resolved a similar problem using a really simple subclass of UIScrollView of my own. You can take a look at it here - https://gist.github.com/ShadeApps/5a29e1cea3e1dc3df8c8. Works like charm for me.
That's how you init it:
scrollViewMain.delegate = self;
scrollViewMain.minimumZoomScale = 1.0;
scrollViewMain.maximumZoomScale = 3.0;
scrollViewMain.contentSize = imageViewMain.frame.size;
scrollViewMain.backgroundColor = [UIColor blackColor];
scrollViewMain.tileContainerView = imageViewMain;
There is awesome blog post about this problem from Peter Steinberger: http://petersteinberger.com/blog/2013/how-to-center-uiscrollview/
I am trying to add a page control to my scroll view, and have followed numerous web tutorials, the majority which use the same code as this tutorial. However, once I place the code into my project, even with me making changes to the code to try to make it work, it just doesn't. I have managed to make the code work for when the page control is pressed, however it just won't work for the page scrolling. My issue is similar to this, although the answers are of no help. Here is my code:
MainViewController.h
#interface MainViewController : UIViewController
{
UIScrollView *svCollegeMain;
UIScrollView *svCollegePage;
UIPageControl *pcCollege;
UIView *viewP1;
}
#property (nonatomic, retain) IBOutlet UIScrollView* svCollegeMain;
#property (nonatomic, retain) IBOutlet UIScrollView* svCollegePage;
#property (nonatomic, retain) IBOutlet UIPageControl * pcCollege;
- (IBAction)changePage;
#end
and MainViewController.m
#implementation MainViewController
#synthesize svCollegeMain, svCollegePage, pcCollege;
- (void)viewDidLoad
{
[super viewDidLoad];
self.svCollegeMain.contentSize = CGSizeMake(960, 332);
self.svCollegePage.contentSize = CGSizeMake(320, 500);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
CGFloat pageWidth = 320;
int page = floor((svCollegeMain.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pcCollege.currentPage = page;
}
- (IBAction)changePage
{
CGRect frame;
frame.origin.x = self.svCollegeMain.frame.size.width * self.pcCollege.currentPage;
frame.origin.y = 0;
frame.size = self.svCollegeMain.frame.size;
[self.svCollegeMain scrollRectToVisible:frame animated:YES];
}
#pragma mark - View lifecycle
- (void)viewDidUnload
{
[super viewDidUnload];
self.svCollegeMain = nil;
self.svCollegePage = nil;
self.pcCollege = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Just incase this makes any difference, my view is set out with a view, then a main scroll view and page control within this view, another view and scroll view (next to each other) within the main scroll view, and finally a final view in the second scroll view (all in IB, did not want too much code), and everything is linked up in IB.
I notice that your MainViewController doesn't declare itself as implementing UIScrollViewDelegate, so I also assume that you've forgotten to set it up as the delegate for the scroll view in IB (otherwise it wouldn't compile).
Since it has no delegate defined, the scroll view won't be calling your scrollViewDidScroll function.
Tim
Try this
HeaderFile:
#interface DemoPageControlViewController : UIViewController <UIScrollViewDelegate>
{
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
BOOL pageControlUsed;
NSMutableArray *imageArray;
int pageNumber;
}
#property (nonatomic, retain) UIScrollView *scrollView;
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *imageArray;
- (IBAction) changePage:(id)sender;
Implementation File:
#import "DemoPageControlViewController.h"
#implementation DemoPageControlViewController
#synthesize pageControl, scrollView, imageArray;
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
imageArray = [[NSMutableArray alloc]init];
[imageArray addObject:#"small_one.png"];
[imageArray addObject:#"small_two.png"];
[imageArray addObject:#"small_three.png"];
[imageArray addObject:#"small_four.png"];
// add the last image to first
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed: [imageArray objectAtIndex:([imageArray count] -1)]]];
imageView.frame = CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
for(int i = 0; i < imageArray.count; i++)
{
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[imageArray objectAtIndex:i]]];
imageView.frame = CGRectMake((scrollView.frame.size.width * i ) + 320 , 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
}
// add the first image to last
imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[imageArray objectAtIndex:0]]];
imageView.frame = CGRectMake(scrollView.frame.size.width * ([imageArray count]+1), 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * ([imageArray count]+ 2), self.scrollView.frame.size.height);
[scrollView setContentOffset:CGPointMake(0, 0)];
[self.view addSubview:scrollView];
[self.scrollView scrollRectToVisible:CGRectMake(scrollView.frame.size.width,0,scrollView.frame.size.width,scrollView.frame.size.height) animated:NO];
}
- (IBAction)changePage :(id)sender
{
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage ;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//pageControlUsed = NO;
NSLog(#"%f", self.scrollView.contentOffset.x);
CGFloat pageWidth = self.scrollView.frame.size.width;
//pageNumber = floor((self.scrollView.contentOffset.x - pageWidth / ([imageArray count]+2)) / pageWidth) + 1 ;
pageNumber = self.scrollView.contentOffset.x / pageWidth;
if(pageNumber == 0)
{
[self.scrollView scrollRectToVisible:CGRectMake((self.scrollView.frame.size.width * [imageArray count]), 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:NO];
pageNumber = [imageArray count];
//self.pageControl.currentPage = pageNumber;
}
else if(pageNumber == ([imageArray count]+1))
{
[self.scrollView scrollRectToVisible:CGRectMake(self.scrollView.frame.size.width, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:NO];
pageNumber = 1;
//self.pageControl.currentPage = pageNumber;
}
self.pageControl.currentPage = pageNumber - 1;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
}
This Code works fine. Try this
I have implemented a circular scroll view.
It's working fine , but after sometimes the scroll view delegates are not getting called.
I have attached the code , what is the bug in it ....
//
// MyScrollViewViewController.h
// MyScrollView
//
// Created by Biranchi on 26/05/09.
// Copyright PurpleTalk 2009. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface MyScrollViewViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIView *view1;
IBOutlet UIView *view2;
IBOutlet UIView *view3;
IBOutlet UILabel *label1;
IBOutlet UILabel *label2;
IBOutlet UILabel *label3;
int viewAtIndex;
int currentOffset;
int firstOffset, lastOffset;
int currentContentInset;
int tempOffset;
NSMutableArray *arr;
}
#end
//
// MyScrollViewViewController.m
// MyScrollView
//
// Created by Biranchi on 26/05/09.
// Copyright PurpleTalk 2009. All rights reserved.
//
#import "MyScrollViewViewController.h"
#implementation MyScrollViewViewController
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
//static int j = 0;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
arr = [[NSMutableArray alloc] init];
[arr addObject:view1];
[arr addObject:view2];
[arr addObject:view3];
//NSLog(#"arr : %#", arr);
scrollView.minimumZoomScale = 1.0f;
scrollView.maximumZoomScale = 2.0f;
scrollView.delegate = self;
//scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
firstOffset = 0;
currentOffset = 320;
lastOffset = 640;
currentContentInset = 320;
CGRect frame;
//Scroll View
frame = [view1 frame];
[view1 setBackgroundColor:[UIColor redColor]];
frame.origin.x = 0;
[view1 setFrame:frame];
frame = [view2 frame];
[view2 setBackgroundColor:[UIColor greenColor]];
frame.origin.x = 320;
[view2 setFrame:frame];
frame = [view3 frame];
[view3 setBackgroundColor:[UIColor blueColor]];
frame.origin.x = 640;
[view3 setFrame:frame];
[scrollView addSubview:view1];
[scrollView addSubview:view2];
[scrollView addSubview:view3];
[scrollView setContentSize:CGSizeMake(3*320, 480)];
[scrollView setContentOffset: CGPointMake(currentOffset,0) animated:NO];
[self.view addSubview:scrollView];
//NSLog(#"Self.view Subviews : %#", [self.view subviews]);
}
#pragma mark -
#pragma mark ScrollView Delegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView1
{
NSLog(#"Will begin dragging ===");
CGPoint offset = [scrollView1 contentOffset];
tempOffset = offset.x;
NSLog(#"Offset : %#", NSStringFromCGPoint(offset));
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView1
{
NSLog(#"ScrollView did end decelerating ");
int i, result;
CGPoint offset = [scrollView1 contentOffset];
currentOffset = offset.x;
NSLog(#"Offset : %#", NSStringFromCGPoint(offset));
if( ( (currentOffset - tempOffset) > 0 ) || ( (currentOffset == tempOffset) && (currentOffset == lastOffset) ) )
{
NSLog(#"Show next page , current : %d, temp : %d", currentOffset, tempOffset);
for(i=0; i<[arr count]; i++)
{
if( [[arr objectAtIndex:i] frame].origin.x == currentOffset )
{
NSLog(#"Current view on screen : %d", i);
break;
}
}
NSLog(#"Before Current offset : %d, last offset : %d", currentOffset, lastOffset);
if( currentOffset == lastOffset )
{
result = i-2;
if(result < 0)
{
result += 3;
}
NSLog(#"Change the frame of object at index : %d", result);
[[arr objectAtIndex:result] setFrame:CGRectMake(currentOffset + 320, 0, 320, 480)];
[scrollView1 setContentSize:CGSizeMake(currentOffset+640,480) ];
lastOffset += 320;
firstOffset += 320;
}
NSLog(#"Current offset : %d, first offset : %d , last offset : %d", currentOffset, firstOffset, lastOffset);
}
else if( ( (currentOffset - tempOffset) < 0 ) || ( (currentOffset == tempOffset) && (currentOffset == firstOffset) ) )
{
//NSLog(#"Show prev page");
for(i=0; i<[arr count]; i++)
{
if( [[arr objectAtIndex:i] frame].origin.x == currentOffset )
{
NSLog(#"==Current view on screen : %d", i);
break;
}
}
NSLog(#"==Before Current offset : %d, First offset : %d", currentOffset, firstOffset);
if( currentOffset == firstOffset )
{
result = i+2;
if(result >= 3)
{
result -= 3;
}
NSLog(#"==Change the frame of object at index : %d", result);
[[arr objectAtIndex:result] setFrame:CGRectMake(currentOffset - 320, 0, 320, 480)];
UIEdgeInsets contentInset = {0,currentContentInset,0,0};
[scrollView1 setContentInset:contentInset ];
firstOffset -= 320;
currentContentInset += 320;
lastOffset -= 320;
}
NSLog(#"==Current offset : %d, first offset : %d, Last Offset : %d", currentOffset, firstOffset, lastOffset);
}
else
{
NSLog(#"Error in offset");
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView1
{
return [[scrollView1 subviews] objectAtIndex:viewAtIndex];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView1 withView:(UIView *)view atScale:(float)scale
{
//NSLog(#"View Zoomed : %#, scale : %f", view, scale);
}
#pragma mark -
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[arr release];
[super dealloc];
}
#end