I am fairly new to xcode and having an issue with a scrollview. The scrollview works fine...however when using storyboards and push combined i have a problem. When first viewing the scrollview it works fine however when you push to a new page then go back to the storyboard with the scrollview it no longer scrolls. Im thinking this has something to do with the didload and maybe i should be using willappear? The code is below. I think i need to change this code somehow so that it reloads the storyboard everytime go back to this storyboard... Has anyone else come across this issue or advise on how to fix?
//
// PrintViewController.m
//
//
#import "PrintViewController.h"
#interface PrintViewController ()
#end
#implementation PrintViewController
#synthesize PrintScroller, rememberContentOffset;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[PrintScroller setScrollEnabled:YES];
// Do any additional setup after loading the view.
}
- (void) viewDidAppear:(BOOL)animated {
[PrintScroller setContentSize:CGSizeMake(300, 595)];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
self.PrintScroller.contentOffset = CGPointMake(0, 0);
}
- (void)viewWillDisappear:(BOOL)animated {
self.rememberContentOffset = self.PrintScroller.contentOffset;
[super viewWillDisappear:animated];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.PrintScroller.contentOffset = CGPointMake(0, self.rememberContentOffset.y);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I suspect your problem is here:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.PrintScroller.contentOffset = CGPointMake(0, self.rememberContentOffset.y);
}
This method could be called by the system repeatedly when the user is scrolling. Since you're setting the content offset each time, the view won't move. You should only do this once and then, say, set self.rememberContentOffset to CGPointZero, and then avoid changing the content offset if the remembered offset is zero. Something like:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (self.rememberContentOffset.y > 0) {
self.PrintScroller.contentOffset = CGPointMake(0, self.rememberContentOffset.y);
self.rememberContentOffset = CGPointZero;
}
}
Related
My ViewController looks like this when initially loaded:
When show button is tapped it must change like this:
my code is:
- (IBAction)show:(id)sender {
[self change];
[tableView reloadData];
}
- (IBAction)close:(id)sender {
[self change];
[tableView reloadData];
}
-(void)change{
//assigning initial bounds to frame-1
CGRect frame1=CGRectMake(0, _pastProcessTV.frame.origin.y, self.view.bounds.size.width, self.pastProcessTV.bounds.size.height);
//assigning new bounds to frame-2
CGRect frame2=CGRectMake(0, **CGFloat y**,self.view.bounds.size.width,***CGFloat height***);
if (_showFullButton.isTouchInside) {
tableView.frame = frame2;
}
else{
tableview.frame = frame1;
}
}
I tried different ways. it is not working.can anyone help me in giving Y-coordinate and width
As you are using autolayout you have to take outlet of topconstraint of the tableview and when you want to expand it set its value to 0
So it will work as expected
if you are using iOS 7
[self.view layoutIfNeeded] is compulsary
If you have to use auto layout, please try like this picture
Make Layout Constraint Property
And try this code
#import "ViewController.h"
#interface ViewController ()
{
CGFloat oldtableViewTopValue;
}
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewTopLC;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
oldtableViewTopValue = _tableViewTopLC.constant;
}
- (IBAction)showBtnAction:(id)sender
{
[UIView animateWithDuration:0.5f animations:^{
_tableViewTopLC.constant = (_tableViewTopLC.constant==oldtableViewTopValue ? 0 : oldtableViewTopValue);
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
#end
Please turn off autolayout from Storyboard
I can't intercept the init function that's getting called when it's getting created inside of the xib file.
I want to add borderline to it when it gets created so that I won't need to add it manually.
.h:
#import <UIKit/UIKit.h>
#interface UITextView (FITAddBorderline)
- (id) init;
- (id) initWithFrame:(CGRect)frame;
#end
.m:
#import "UITextView+FITAddBorderline.h"
#implementation UITextView (FITAddBorderline)
- (id) init
{
self = [super init];
if (self) {
[self addBorderline];
}
return self;
}
- (id) initWithFrame:(CGRect)frame {
self = [super init];
if (self) {
self.frame = frame;
[self addBorderline];
}
return self;
}
- (void) addBorderline {
//To make the border look very close to a UITextField
[self.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[self.layer setBorderWidth:2.0];
//The rounded corner part, where you specify your view's corner radius:
self.layer.cornerRadius = 5;
self.clipsToBounds = YES;
}
#end
Views that come from NIBs are initialized with initWithCoder:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self addBorderline];
}
return self;
}
As a side note, I would recommend changing what you are doing and use a subclass instead of a category. You can get yourself into some trouble overriding methods in a category. See more info here.
You just need to implement the awakeFromNib method:
-(void)awakeFromNib
{
[super awakeFromNib];
[self addBorderline];
}
I know this question has been asked a countless number of times, although I have not been able to get it to work at all, literally no answer has worked, maybe I'm not copying the code across correctly, but either way it wont work.
Anyway, my application's view controller layout is as follows, note that this is a Tabbed Application, NOT a single View Application:
Master Tab Bar Controller > Branches off into multiple Navigation Bar Controllers (all referencing to the same CustomNavigationController class) > Under each Nav Controller are a number of UIViewControllers, some of which are referencing custom view controller classes. (see pic for a visual representation of the hierarchy)
My question is: how can I lock the orientation of all pages in my application to portrait mode ONLY, however allow some pages (UIViewControllers) to be able to rotate to landscape if the user rotates the device? (The pages marked with a star, in the image above are the ones I would like to ALLOW rotation for)
Remember the view controllers that I want to allow rotation for are children to a Navigation controller which is also a child to a Tab Bar Controller. Also, note that one of the View controllers isn't under a Navigation controller, it is just under the Tab Bar controller, not sure how much this affects though.
Thank you so much
Code from the relevant classes of my app
Tab Bar Controller Code (note there is not meaningful code in here as I never used to have a class for this)
#interface TabBarController ()
#end
#implementation TabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Navigation Controller Class (Also never had a class for this
#interface NavigationBar ()
#end
#implementation NavigationBar
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"NavigationController";
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Home Page Class (Must be locked in portrait)
#interface HomePage ()
#end
#implementation HomePage
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"HomePage";
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// If the condition is not true/not YES, than create and show alert.
if (![[NSUserDefaults standardUserDefaults]
boolForKey:#"didShowOneTimeAlert"]) {
//Define and Edit the Alert details.
UIAlertView *zoomTip = [[UIAlertView alloc] initWithTitle:#"Tips" message:#"On all web site and map pages, pinch in and out to zoom. \n \n On the 'Program' page, tap on a session to view more details." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil];
//Show the alert
[zoomTip show];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"didShowOneTimeAlert"];
[[NSUserDefaults standardUserDefaults] synchronize];
} // End if
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Map Class (A page that displays a map and MUST be able to rotate)
#interface MezzanineLevelMap ()
#end
#implementation MezzanineLevelMap
#synthesize scrollView, imageView;
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Mezzanine Level"]];
self.imageView = tempImageView;
scrollView.maximumZoomScale = 1;
scrollView.minimumZoomScale = .25;
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
scrollView.zoomScale = .25;
// Change scroll view sizes according to the screen size
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize result = [[UIScreen mainScreen] bounds].size;
if (result.height == 480) {
[scrollView setFrame:CGRectMake(0, 5, 320, 475)];
} else {
[scrollView setFrame:CGRectMake(0, 5, 320, 563)];
} // End if
} // End if
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Just implement the following in your view controller (iOS 6+):
- (BOOL)shouldAutorotate {
return NO;
}
In each viewcontroller you can write following code and return yes or no as per requirement.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES/NO;
}
Very good description of fixing this is at
http://koreyhinton.com/blog/lock-screen-rotation-in-ios8.html
I have a custom view that I would like to use in Interface Builder. It's setup like the following:
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initialize];
}
return self;
}
-(void)initialize {
....
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
...frame stuff
}
but when I use the class in interface builder it is not receiving the frame, just it's bounds. Meaning the origin stays at 0,0 but the width/height do get set correctly. If anyone can point out whats wrong I would be very greatful.
UPDATE:
Just spotted this in IB:
Override - (void)awakeFromNib; for your custom view. At that point, your frame should be setup.
I have a child view controller looking like this:
I am embedding it into another parent view controller,
#implementation ContainmentViewController
- (id)initWithCoder:(NSCoder *)decoder {
if(self = [super initWithCoder:decoder]) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.prototypeVC = [self.storyboard instantiateViewControllerWithIdentifier:#"PrototypeViewController"];
[self addChildViewController:self.prototypeVC];
[self.view addSubview:self.prototypeVC.view];
[self.prototypeVC didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
This is how it should look like in the original child VC:;
This is how it looks like in the ContainmentVC:
What am I doing wrong?
NOTE: I have to pick "Wants full screen" on the ChildVC otherwise I will see a 20px white space at the top.
I got fed up with playing with storyboard.
So I unchecked Wants Full Screen
and added the following:
self.prototypeVC.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
Everything works now