NSStackView, fill view when one of the subviews is hidden - objective-c

I have a vertical NSStackView that has this behavior. It has two subviews, one of them at top of the stack view, that will have a fixed height.
Then, there is another view that will cover the remaining space in the view. Similar to the image below. My current code already displays the view as below:
I want to have a behavior where, when I hide the top view, or ViewA, the ViewB takes the height of the entire stack view. Like this image:
I'm doing this programmatically, but when I set the ViewA as hidden, the ViewB doesn't take the entire space available. Leaving the ViewA space there.
My current code already shows the UI like in the first image and it is:
#interface CutsomStackView : NSSTackView
#property (nonatomic) NSView *viewA;
#property (nonatomic) NSView *viewB;
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views;
#end
#implementation CutsomStackView
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views
{
if (!(self = [super initWithFrame:frame]))
return nil;
_viewA = views[0];
_viewB = views[1];
self.detachesHiddenViews = YES;
self.orientation = NSUserInterfaceLayoutOrientationVertical;
self.spacing = 0;
self.distribution = NSStackViewDistributionFill;
CGFloat viewAHeight = NSHeight(_viewA.frame);
[self addSubview:_viewA];
[self addSubview:_viewB];
_viewA.translatesAutoresizingMaskIntoConstraints = NO;
_viewB.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = #{
_viewA,
_viewB
};
NSDictionary *metrics = #{
#"viewAHeight": #(viewAHeight)
};
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:UNLOCALIZED_STRING("V:|[_viewA(viewAHeight)][_viewB]|") options:NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing metrics:metrics views:views]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:UNLOCALIZED_STRING("H:|[_viewA]|") options:0 metrics:nil views:views]];
return self;
}
#end
I'm not sure what do I need to add to allow the ViewB to grow in size when the ViewA is hidden.
In addition, after I hide the viewB, I call the layoutSubtreeIfNeeded method.

At the end the problem was in three different things:
Using -[NSStackView addSubView:] instead of -[NSStackView addArrangedSubview:]
Using a constraint to organize the views correctly.
The hugging priority of the views.
The fixed code is:
#interface CutsomStackView : NSSTackView
#property (nonatomic) NSView *viewA;
#property (nonatomic) NSView *viewB;
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views;
#end
#implementation CutsomStackView
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views
{
if (!(self = [super initWithFrame:frame]))
return nil;
_viewA = views[0];
_viewB = views[1];
self.detachesHiddenViews = YES;
self.orientation = NSUserInterfaceLayoutOrientationVertical;
self.spacing = 0;
self.distribution = NSStackViewDistributionFill;
CGFloat viewAHeight = NSHeight(_viewA.frame);
[self addArrangedSubview:_viewA];
[self addArrangedSubview:_viewB];
_viewA.translatesAutoresizingMaskIntoConstraints = NO;
[_viewA setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical];
[_viewA.heightAnchor constraintEqualToConstant:topBarViewHeight].active = YES;
_viewB.translatesAutoresizingMaskIntoConstraints = NO;
[_viewB setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationVertical];
return self;
}
#end

Related

How to add swiple gesture with 3 buttons in a xib?

I have a table view where i m adding a cell for the content of the table view and i need to add swipeable gesture with 3 buttons in that that table cell.
u haven't provide enough info about how you are implementing the tableview cell but i assume that u are using the xib file and also i assume that u want to display the 3 button when table view cell is swiped ..
first of all u should subclass the table view cell in my example i named the cell class as CustomTableCell
in this cell's xib file i am adding the a view and 3 buttons, it is something look like below image
in the above image swipeView should be on top of content view and it holds your swipe gestures
for example in CustomTableCell.h file
#import <UIKit/UIKit.h>
#interface CustomTableCell : UITableViewCell
+ (id)createMenuCell;
#property (weak, nonatomic) IBOutlet UIView *swipeView;
#property (weak, nonatomic) IBOutlet UIButton *button3;
#property (weak, nonatomic) IBOutlet UIButton *button2;
#property (weak, nonatomic) IBOutlet UIButton *button1;
#property (assign, nonatomic) BOOL showButton;
- (IBAction)buttonOneAction:(id)sender;
- (IBAction)buttonTwoAction:(id)sender;
- (IBAction)buttonThreeAction:(id)sender;
#end
and in CustomTableCell.m file
#import "CustomTableCell.h"
#implementation CustomTableCell
#define MAX_LEFT 160 //set the how much view has to be move
#define ANIMATION_DUR 0.3
+ (id)createMenuCell
{
NSArray *xibElements = [[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:nil options:nil];
for(id item in xibElements)
{
if([item isKindOfClass:[CustomTableCell class]])
{
return (CustomTableCell *)item;
}
}
return nil;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
[self setUpGestures];
}
return self;
}
- (void)awakeFromNib {
// Initialization code
_showButton = NO; //simple avoid unwanted swipes when showing the buttons
[self setUpGestures];
}
- (void)setUpGestures{
UISwipeGestureRecognizer *swipeLeftGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(swipeLeftGestureAction)]; //to open
swipeLeftGesture.direction = UISwipeGestureRecognizerDirectionLeft; //set the direction to swipe
[self.swipeView addGestureRecognizer:swipeLeftGesture];
UISwipeGestureRecognizer *swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightGestureAction)]; //this is for closing
[self.swipeView addGestureRecognizer:swipeRightGesture];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
//button actions
- (IBAction)buttonOneAction:(id)sender {
NSLog(#"button one action");
}
- (IBAction)buttonTwoAction:(id)sender {
NSLog(#"button two action");
}
- (IBAction)buttonThreeAction:(id)sender {
NSLog(#"button three action");
}
//hear u are showing the buttons with left swipe
- (void)swipeLeftGestureAction
{
if(!_showButton)
{
CGRect destRect = self.swipeView.frame;
destRect.origin.x = -MAX_LEFT;
[UIView animateWithDuration:ANIMATION_DUR animations:^{
self.swipeView.frame = destRect;
} completion:^(BOOL finished) {
_showButton = YES;
}];
}
}
//hear u are hiding the buttons if it is shown
- (void)swipeRightGestureAction
{
if(_showButton)
{
CGRect destRect = self.swipeView.frame;
destRect.origin.x = 0;
[UIView animateWithDuration:ANIMATION_DUR animations:^{
self.swipeView.frame = destRect;
} completion:^(BOOL finished) {
_showButton = NO;
}];
}
}
Note: above is just i assumed so final result will be like below

UITextField shadow does not display when editing

I want to draw the text in an UITextField with a shadow. In order to do this, I have subclassed UITextField, and implemented the drawTextInRect: method as follows:
- (void)drawTextInRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// Create shadow color
float colorValues[] = {0.21875, 0.21875, 0.21875, 1.0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef shadowColor = CGColorCreate(colorSpace, colorValues);
CGColorSpaceRelease(colorSpace);
// Create shadow
CGSize shadowOffset = CGSizeMake(2, 2);
CGContextSetShadowWithColor(context, shadowOffset, 0, shadowColor);
CGColorRelease(shadowColor);
// Render text
[super drawTextInRect:rect];
}
This works great for when the text field is not editing, but as soon as editing begins, the shadow disappears. Is there anything I am missing?
Here is the code for following component
#interface AZTextField ()
- (void)privateInitialization;
#end
#implementation AZTextField
static CGFloat const kAZTextFieldCornerRadius = 3.0;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
[self privateInitialization];
return self;
}
// In case you decided to use it in a nib
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (!self) return nil;
[self privateInitialization];
return self;
}
- (void)privateInitialization
{
self.borderStyle = UITextBorderStyleNone;
self.layer.masksToBounds = NO;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
self.layer.shadowOpacity = 0.5f;
self.layer.backgroundColor = [UIColor whiteColor].CGColor;
self.layer.cornerRadius = 4;
// This code is better to be called whenever size of the textfield changed,
// so if you plan to do that you can add an observer for bounds property
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:kAZTextFieldCornerRadius];
self.layer.shadowPath = shadowPath.CGPath;
}
#end
Couple of things to consider:
You want to set borderStyle to none, otherwise you'll end up with
UIKit putting subviews into your textfield
Depending on the Xcode
version you might want to link QuartzCore and to #import
<QuartzCore/QuartzCore.h>
For more complex appearance you can still
use shadow properties of the layer and move the drawing code itself
into the drawRect: method, but jake_hetfield was right if you
override drawRect you don't want to call super, especially in the end
of the method
As for the text drawing (you can see that it sticks to
close to the component borders), you have a separate
drawTextInRect: and drawPlaceholderInRect: method that draws the
text and placeholder respectively
You can use UIColor method for
colors and call CGColor property, it makes code more readable and
easier to maintain
Hope that helps!
Inspired by #jake_hetfield answer I created a custom UITextField that uses an internal label to do the drawing, check it out:
ShadowTextField .h file
#import <UIKit/UIKit.h>
#interface ShadowTextField : UITextField
// properties to change the shadow color & offset
#property (nonatomic, retain) UIColor *textShadowColor;
#property (nonatomic) CGSize textShadowOffset;
- (id)initWithFrame:(CGRect)frame
font:(UIFont *)font
textColor:(UIColor *)textColor
shadowColor:(UIColor *)shadowColor
shadowOffset:(CGSize)shadowOffset;
#end
ShadowTextField .m file
#import "ShadowTextField.h"
#interface ShadowTextField ()
#property (nonatomic, retain) UILabel *internalLabel;
#end
#implementation ShadowTextField
#synthesize internalLabel = _internalLabel;
#synthesize textShadowColor = _textShadowColor;
#synthesize textShadowOffset = _textShadowOffset;
- (id)initWithFrame:(CGRect)frame
font:(UIFont *)font
textColor:(UIColor *)textColor
shadowColor:(UIColor *)shadowColor
shadowOffset:(CGSize)shadowOffset
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
// register to my own text changes notification, so I can update the internal label
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleUITextFieldTextDidChangeNotification)
name:UITextFieldTextDidChangeNotification
object:nil];
self.font = font;
self.textColor = textColor;
self.textShadowColor = shadowColor;
self.textShadowOffset = shadowOffset;
}
return self;
}
// when the user enter text we update the internal label
- (void)handleUITextFieldTextDidChangeNotification
{
self.internalLabel.text = self.text;
[self.internalLabel sizeToFit];
}
// init the internal label when first needed
- (UILabel *)internalLabel
{
if (!_internalLabel) {
_internalLabel = [[UILabel alloc] initWithFrame:self.bounds];
[self addSubview:_internalLabel];
_internalLabel.font = self.font;
_internalLabel.backgroundColor = [UIColor clearColor];
}
return _internalLabel;
}
// override this method to update the internal label color
// and to set the original label to clear so we wont get two labels
- (void)setTextColor:(UIColor *)textColor
{
[super setTextColor:[UIColor clearColor]];
self.internalLabel.textColor = textColor;
}
// override this method to update the internal label text
- (void)setText:(NSString *)text
{
[super setText:text];
self.internalLabel.text = self.text;
[self.internalLabel sizeToFit];
}
- (void)setTextShadowColor:(UIColor *)textShadowColor
{
self.internalLabel.shadowColor = textShadowColor;
}
- (void)setTextShadowOffset:(CGSize)textShadowOffset
{
self.internalLabel.shadowOffset = textShadowOffset;
}
- (void)drawTextInRect:(CGRect)rect {
// don't draw anything
// we have the internal label for that...
}
- (void)dealloc {
[_internalLabel release];
[_textShadowColor release];
[super dealloc];
}
#end
Here is how you use it in your view controller
- (void)viewDidLoad
{
[super viewDidLoad];
ShadowTextField *textField = [[ShadowTextField alloc] initWithFrame:CGRectMake(0, 0, 320, 30)
font:[UIFont systemFontOfSize:22.0]
textColor:[UIColor whiteColor]
shadowColor:[UIColor redColor]
shadowOffset:CGSizeMake(0, 1) ] ;
textField.text = #"This is some text";
textField.backgroundColor = [UIColor blackColor];
[self.view addSubview:textField];
}
You could try to do the drawing of the label yourself. Remove
[super drawTextInRect:rect]
And instead draw your own label. I haven't tried this but it could look something like this:
// Declare a label as a member in your class in the .h file and a property for it:
UILabel *textFieldLabel;
#property (nonatomic, retain) UILabel *textFieldLabel;
// Draw the label
- (void)drawTextInRect:(CGRect)rect {
if (self.textFieldLabel == nil) {
self.textFieldLabel = [[[UILabel alloc] initWithFrame:rect] autorelease];
[self.view addSubview:myLabel];
}
self.textFieldLabel.frame = rect;
self.textFieldLabel.text = self.text;
/** Set the style you wish for your label here **/
self.textFieldLabel.shadowColor = [UIColor grayColor];
self.textFieldLabel.shadowOffset = CGSizeMake(2,2);
self.textFieldLabel.textColor = [UIColor blueColor];
// Do not call [super drawTextInRect:myLabel] method if drawing your own text
}
Stop calling super and render the text yourself.
Have your tried with the standard shadow properties of the CALayer? it usually is enough and it is lot simpler. Try something like this with a regular UITextField:
self.inputContainer.layer.shadowColor=[UIColor blackColor].CGColor;
self.inputContainer.layer.shadowRadius=8.0f;
self.inputContainer.layer.cornerRadius=8.0f;
self.inputContainer.layer.shadowOffset=CGSizeMake(0, 4);
You need to import QuartzCore first of course!
#import <QuartzCore/QuartzCore.h>

Infinite UIScrollView not working on iOS 4.3

I try to build a endless scrolling UIScrollView. So far I took the apple sample "StreetScroller". So all I do is setting the contentOffset back when it reaches the end of the scroll view.
Override -layoutSubviews of the UIScrollView:
- (void)layoutSubviews
{
CGFloat contentWidth = [self contentSize].width;
CGPoint contentOffset = [self contentOffset];
CGFloat centerOffsetX = (contentWidth - [self bounds].size.width) / 2.0;
CGFloat distanceFromCenter = contentOffset.x - centerOffsetX;
if (ABS(distanceFromCenter) > (contentWidth / 4.0)) {
contentOffset = CGPointMake(centerOffsetX, contentOffset.y);
[super setContentOffset:contentOffset];
}
}
Now on iOS 5 this works like a charm. But on iOS 4.3 it's not working. As soon as I call [super setContentOffset:contentOffset] it stoops scrolling because next time -layoutSubviews get's called the [self contentOffset] does not return the contentOffset that was set.
I know there are a lot a questions about infinite UIScrollViews, but one of these has fixed this problem!
Try this One. This Code is Working Properly for me on iOS 4.3
RootViewController.h
#class ViewControllerForDuplicateEndCaps;
#interface RootViewController : UIViewController {
ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
}
#property (nonatomic, retain) ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender;
#end
RootViewController.m
#import "RootViewController.h"
#import "ViewControllerForDuplicateEndCaps.h"
#import "InfiniteScrollViewAppDelegate.h"
#implementation RootViewController
#synthesize viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender {
InfiniteScrollViewAppDelegate *delegate = (InfiniteScrollViewAppDelegate*)[[UIApplication sharedApplication] delegate];
if(self.viewControllerForDuplicateEndCaps == nil) {
ViewControllerForDuplicateEndCaps *temp = [[ViewControllerForDuplicateEndCaps alloc] initWithNibName:#"ViewControllerForDuplicateEndCaps" bundle:nil];
self.viewControllerForDuplicateEndCaps = temp;
[temp release];
}
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[delegate.navigationController pushViewController:self.viewControllerForDuplicateEndCaps animated:YES];
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end
ViewControllerForDuplicateEndCaps.h
#import <UIKit/UIKit.h>
#interface ViewControllerForDuplicateEndCaps : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
}
#property (nonatomic, retain) UIScrollView *scrollView;
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position;
#end
ViewControllerForDuplicateEndCaps.m
#import "ViewControllerForDuplicateEndCaps.h"
#implementation ViewControllerForDuplicateEndCaps
#synthesize scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
// add the last image (image4) into the first position
[self addImageWithName:#"image4.jpg" atPosition:0];
// add all of the images to the scroll view
for (int i = 1; i < 5; i++) {
[self addImageWithName:[NSString stringWithFormat:#"image%i.jpg",i] atPosition:i];
}
// add the first image (image1) into the last position
[self addImageWithName:#"image1.jpg" atPosition:5];
scrollView.contentSize = CGSizeMake(1920, 416);
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position {
// add image to scroll view
UIImage *image = [UIImage imageNamed:imageString];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(position*320, 0, 320, 416);
[scrollView addSubview:imageView];
[imageView release];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
NSLog(#"%f",scrollView.contentOffset.x);
// The key is repositioning without animation
if (scrollView.contentOffset.x == 0) {
// user is scrolling to the left from image 1 to image 4
// reposition offset to show image 4 that is on the right in the scroll view
[scrollView scrollRectToVisible:CGRectMake(1280,0,320,416) animated:NO];
}
else if (scrollView.contentOffset.x == 1600) {
// user is scrolling to the right from image 4 to image 1
// reposition offset to show image 1 that is on the left in the scroll view
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end

Popover with no size

I made a popover class that I could call easily for basic popovers - you give it data and set the size and it should do the rest.
This was working fine until iOS5, now the popover opens but with just the border, no white space or content at all.
I've searched and searched, any ideas you could throw my way would be great.
#protocol BasicPickerDelegate
- (void)basicPickerItemSelected:(NSMutableDictionary *)thisDic;
#end
#interface BasicPickerController : UITableViewController {
// data
IBOutlet NSMutableArray *theData;
// stuff to set
IBOutlet int myWidth;
IBOutlet int myHeight;
IBOutlet int myPopoverNum;
// delegate
id<BasicPickerDelegate> delegate;
}
#property (nonatomic, retain) IBOutlet NSMutableArray *theData;
#property (nonatomic, assign) IBOutlet int myWidth;
#property (nonatomic, assign) IBOutlet int myHeight;
#property (nonatomic, assign) IBOutlet int myPopoverNum;
#property (nonatomic, assign) id<BasicPickerDelegate> delegate;
- (void)setSize;
- (void)checkData;
#end
Then the setSize function is viewDidLoad
- (void)setSize {
if (!myWidth || !myHeight) {
NSLog(#"WIDTH AND HEIGHT NOT SET, SETTING DEFAULTS");
myWidth = 100;
myHeight = 100;
}
self.contentSizeForViewInPopover = CGSizeMake(myWidth, myHeight);
}
Then I call it like this:
- (IBAction)showBasicPopover:(id)sender {
// Show Basic Popover - can be reused
if (basicPicker != nil) {
self.basicPicker = nil;
[self.basicPicker release];
}
self.basicPicker = [[[BasicPickerController alloc] initWithStyle:UITableViewStylePlain] autorelease];
basicPicker.delegate = self;
self.basicPickerPopover = [[[UIPopoverController alloc]
initWithContentViewController:basicPicker] autorelease];
// Give popover the data it needs
NSMutableDictionary *sizeDic = [self returnPopoverSize:[sender tag]];
self.basicPicker.myHeight = [[sizeDic objectForKey:#"height"] intValue];
self.basicPicker.myWidth = [[sizeDic objectForKey:#"width"] intValue];
self.basicPicker.myPopoverNum = [sender tag];
[basicPicker viewDidLoad];
self.basicPicker.theData = [self returnPopoverData:[sender tag]];
NSLog(#"giving popover dic (%d) with %d derps", [sender tag], [self.basicPicker.theData count]);
// Set display settings and show popover
[basicPicker viewWillAppear:YES];
CGRect popoverRect = [self.view convertRect:[sender frame]
fromView:[sender superview]];
[self.basicPickerPopover presentPopoverFromRect:popoverRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
When I run it, the WIDTH AND HEIGHT NOT SET, SETTIN DEFAULTS dialogue comes up. For some reason it's not reading in the values it's given. Though with some fiddling, even if I can get it to read them in it don't think they are valid and overrides them.
edit: So basically:
With setSize being called in viewDidLoad it doesn't know what the width and height is. So it sets the default.
If setSize isn't called in viewDidLoad, it comes up with "no size" - ie it has popover border but no content in it at all.
When setSize is called in viewWillAppear, viewDidAppear or anything like that (after viewDidLoad) it doesn't actually set the size of the popover.
Finally figured this out.
I needed to assign the width/height variables after creating the popover but before initialising it.
Revised code below:
self.basicPicker = [[[BasicPickerController alloc] initWithStyle:UITableViewStylePlain] autorelease];
// Give popover the data it needs
basicPicker.delegate = self;
NSMutableDictionary *sizeDic = [self returnPopoverSize:[sender tag]];
self.basicPicker.myHeight = [[sizeDic objectForKey:#"height"] intValue];
self.basicPicker.myWidth = [[sizeDic objectForKey:#"width"] intValue];
self.basicPicker.myPopoverNum = [sender tag];
// Now init
self.basicPickerPopover = [[[UIPopoverController alloc]
initWithContentViewController:basicPicker] autorelease];
[basicPicker viewDidLoad];

UIScrollView Controller - changing a scrollview property from a nested nib?

I'm currently working on an application which uses a scrollViewController as I need to have a vertical and horizontal scroll so it loads the NIB's nested.
This all worked fine but when I add a UIPicker into one of my nested nibs it does not scroll, I have read this can easily be fixed by disabling scrolling in the UIScrollView however I am not 100% sure how to do this from the other class.
scrollViewController.h
#interface scrollViewController : UIViewController <UIScrollViewDelegate>{
UIScrollView* scrollView;
UIPageControl* pageControl;
UIScrollView *vScrollView;
UIScrollView *hScrollView;
BOOL pageControlBeingUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl* pageControl;
#property (nonatomic, retain) UIScrollView *vScrollView;
#property (nonatomic, retain) UIScrollView *hScrollView;
- (IBAction)changePage;
#end
scrollViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect bounds = self.view.bounds;
// main guy is a horizontal scroller
hScrollView = [[UIScrollView alloc] initWithFrame:bounds];
hScrollView.contentSize = CGSizeMake(bounds.size.width * 2, bounds.size.height);
hScrollView.delegate = self;
[self.view addSubview:hScrollView];
// the horizontal scroller contains a vertical scroller
vScrollView = [[UIScrollView alloc] initWithFrame:bounds];
vScrollView.contentSize = CGSizeMake(bounds.size.width, bounds.size.height * 2);
vScrollView.delegate = self;
[hScrollView addSubview:vScrollView];
2ndView *view2 = [[2ndView alloc] initWithNibName:#"2ndView" bundle:nil];
[vScrollView addSubview:view2.view];
vScrollView.contentOffset = CGPointMake(0, bounds.size.height);
mainView *vc = [[mainView alloc] initWithNibName:#"mainView" bundle:nil];
vc.view.frame = CGRectOffset(bounds, 0, bounds.size.height);
[vScrollView addSubview:vc.view];
// 3rd View
ValidatorView *vc3 = [[ValidatorView alloc] initWithNibName:#"ValidatorView" bundle:nil];
vc3.view.frame = CGRectOffset(bounds, bounds.size.width, 0);
[hScrollView addSubview:vc3.view];
// enable paging in both directions
hScrollView.pagingEnabled = TRUE;
vScrollView.pagingEnabled = TRUE;
hScrollView.showsHorizontalScrollIndicator = FALSE;
vScrollView.showsVerticalScrollIndicator = FALSE;
hScrollView.alwaysBounceHorizontal = FALSE;
vScrollView.alwaysBounceVertical = FALSE;
vScrollView.canCancelContentTouches = NO;
vScrollView.delaysContentTouches = NO;
hScrollView.bounces = FALSE;
vScrollView.bounces = FALSE;
}
In mainView.m I have created a button which brings a UIPicker onto the view, however I want it to update the vScrollView in scrollViewController with the property
vScrollView.scrollEnabled = NO;
Any help on this would be appreciated.
Thanks Aaron
You can have an instance variable in your application delegate class that points to your scrollViewController and then you can use scrollEnabled of that instance variable to NO