XCode 4.5 UiScrollView issue - objective-c

I'm trying to implement an UIScrollView with Page Control with an array of images. I used same piece of code of another project, but it doesn't work with Xcode 4.5. ScrollView frame properties are all 0 while debugging, but the scrollview Outlet is well connected. Images doesn't show in the scroll. It is really strange. I have observed that properties are not synthesized automatically like previous versions. Here is the code:
#interface dashboardViewController : UIViewController <UIScrollViewDelegate>{
BOOL pageControlBeingUsed;
}
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (strong, nonatomic) IBOutlet UIPageControl *pageControl;
- (IBAction)changePage;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"fondo.jpg"]]];
pageControlBeingUsed=NO;
scrollView.delegate=self;
[self buildScrollView];
// Do any additional setup after loading the view.
}
-(void)buildScrollView{
NSArray *imagesQueue = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"icoblog.png"], [UIImage imageNamed:#"icogaleria.png"], [UIImage imageNamed:#"icobio.png"], nil];
for(int i = 0; i < imagesQueue.count; ++i) {
UIImageView *image = [[UIImageView alloc] initWithImage:[imagesQueue objectAtIndex:i]];
CGFloat xOrigin = i * (scrollView.frame.size.width);
image.frame = CGRectMake(xOrigin, 0, scrollView.frame.size.width, scrollView.frame.size.height);
[scrollView addSubview:image];
image=nil;
}
scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * imagesQueue.count, self.scrollView.frame.size.height);
}
Many thanks for your help.

Select your scrollview in the storyboard and untick the "auto layout" under file properties

Try pushing "self." infront of all the "scrollView" you don't have it.

Related

How to set values of subclassed UIView properties when loading subclass from a xib

I have a subclassed UIView called BannerHeaderView, and designed the way I want it layed out in an xib. I have set the xib class to BannerHeaderView. I have a UILabel and a UIImageView which I have connected in IB.
The problem is that when I go to set the values of these subViews after initialising my BannerHeaderView in a ViewController, the label and image view are null. I have tried setting them in init also.
Code for BannerHeaderView.h:
#interface BannerHeaderView : UIView
#property (strong, nonatomic) IBOutlet UIImageView *bannerImage;
#property (strong, nonatomic) IBOutlet UILabel *headerLabel;
-(void)setTitle:(NSString *)title;
-(void)setImageFile:(PFFile *)imageFile;
#end
Code for BannerHeaderView.m:
#implementation BannerHeaderView
#synthesize headerLabel, bannerImage;
-(id)init{
self = [super init];
if (self) {
[self customInit];
}
return self;
}
-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self customInit];
}
return self;
}
-(void)customInit{
UIView *contentView = [[[NSBundle mainBundle] loadNibNamed:#"BannerHeaderView"
owner:self
options:nil] objectAtIndex:0];
[self addSubview:contentView];
contentView.frame = self.bounds;
}
-(void)setTitle:(NSString *)title{
NSLog(#"HEADER = %#", headerLabel);
headerLabel.text = title;
}
And I am creating the BannerHeaderImage in my ViewController like so:
bannerHeader = [[BannerHeaderView alloc]initWithFrame:CGRectMake(0, 0, screenWidth, bannerHeight + segmentedHeaderHeight)];
[bannerHeader setTitle:#"I AM THE NEW TITLE"];
The log tells me that the headerLabel is null.
Questions:
How do I set the values of these subviews?
Should I just design the layout of this programatically?
Thanks for your time.
P.S. I have spent hours researching this and I can't find a solution. I did find similar questions on SO but none with suitable answers to enable me to solve my problem...
Please set the class BannerHeaderView to File's Owner like this

Trying to fix subview flipping and now subview buttons no longer work?

I have a view which includes two subviews. I had it working so that only one subview was shown at a time and each subview had a button and when the button was clicked the subview would flip over and the next subview would appear. The problem was that it appeared as though the entire view was flipping. After reading on this site about how to solve the problem I attempted to add the subviews to a container and flip that instead. However now, although my first subview is showing up when I press the button it no longer flip. It doesn't do anything. I put a log statement in the method which flips the subviews, as well as a breakpoint and as far as I can tell it no longer gets called. I'm very new to xcode and objective c and delegates and I have no idea how to proceed. Any help would be appreciated. Thanks.
I have included the relevant code here:
The header for the ViewController
#interface ExerciseViewController : UIViewController<ExerciseSubViewDelegate>
//stuff for subviews
#property (nonatomic, strong) ExerciseSubViewImage *subViewImage;
#property (nonatomic, strong) ExerciseSubViewText *subViewText;
#property UIView *panel;
#end
This is the code for the ViewController:
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
#synthesize subViewImage, subViewText;
- (void)viewDidLoad
{
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
}
-(ExerciseSubViewImage *)subViewImage
{
if (!subViewImage)
{
CGRect subViewImageFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewImage = [[ExerciseSubViewImage alloc] initWithFrame:subViewImageFrame];
[_panel addSubview:subViewImage];
}
return subViewImage;
}
-(ExerciseSubViewText *)subViewText
{
if (!subViewText)
{
CGRect subViewTextFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewText = [[ExerciseSubViewText alloc] initWithFrame:subViewTextFrame];
self.subViewText.backgroundColor = [UIColor blueColor];
[_panel addSubview:subViewText];
}
return subViewText;
}
-(void)exerciseSubViewImagePressed
{
[UIView transitionWithView:_panel
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[subViewImage removeFromSuperview];
[_panel addSubview:subViewText];
}
completion: nil];
//This is how I did it before I added the container
/*[UIView transitionFromView:subViewImage
toView:subViewText
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewText.delegate = self;*/
NSLog(#"Ipushedtheimage");
}
-(void)exerciseSubViewTextPressed
{//I haven't updated this yet
[UIView transitionFromView:subViewText
toView:subViewImage
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewImage.delegate = self;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
subViewImage = nil;
subViewText = nil;
}
#end
This is the code for the delegate
#import
#protocol ExerciseSubViewDelegate <NSObject>
-(void) exerciseSubViewImagePressed;
-(void) exerciseSubViewTextPressed;
#end
I am also added the code for the first subview:
#import
#import "ExerciseSubViewDelegate.h"
#interface ExerciseSubViewImage : UIView
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, assign) id<ExerciseSubViewDelegate>delegate;
#property (strong, nonatomic) UIImageView *exerciseImageView;
#end
#import "ExerciseSubViewImage.h"
#import "UIImage+animatedGIF.h"
#implementation ExerciseSubViewImage
#synthesize button;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialization code
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect buttonFrame = CGRectMake(50,200,100,35);
self.button.frame = buttonFrame;
[self.button setTitle:#"Image"forState:UIControlStateNormal];
[self.button addTarget:self
action:#selector(buttonTouched)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
_exerciseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50,20,160,158)];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"AppleLogo" withExtension:#"gif"];
_exerciseImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
[self addSubview:self.exerciseImageView];
}
return self;
}
-(void)buttonTouched
{
NSLog(#"imagebuttonpressed");
[self.delegate exerciseSubViewImagePressed];
}
Again, any help would be appreciate. I know I'm probably just not understanding something simple.
Ok. This took me all weekend but I finally figured it out on my own. I thought I would shere the answer here in case anyone else ever has a similar problem. After trying several other approaches I finally went back to the approach I used here and started inserting a whole bunch of NSLogs to determine the order that every thing was executing in. What I finally ended up doing was changing this: (all in the top ViewController)
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
to this:
//create panel
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, s self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
//Set the subview delegates
self.subViewImage.delegate = self;
self.subViewText.delegate = self;

My animation won't start

I've done this code to start animation when i click a button, when I click the button is should change what the button says and start the animation, but it only changes what the button says ? Is there anything wrong with my code?
#synthesize SwishImage;
#synthesize SwishButton;
- (IBAction) Swish {
if (SwishImage.isAnimating) {
[SwishImage stopAnimating];
[SwishButton setTitle:#"Swish" forState:UIControlStateNormal];
} else {
[SwishImage startAnimating];
[SwishButton setTitle:#"Searching" forState:UIControlStateNormal];
}
}
- (void)viewdidload
{
NSArray * SwishArray;
SwishArray = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"Orange_dot.png"],
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
nil];
SwishImage.animationImages=SwishArray;
SwishImage.animationDuration = 1;
SwishImage.animationRepeatCount = 0;
[super viewDidLoad];
}
When I copied this into an empty Xcode project and linked everything correctly in Interface Builder the image view started animating. I assume something isn't correctly linked in Interface Builder.
That being said, your code is a bit awkward from a standards perspective. Variable names should begin with a lower case letter (and that includes properties). You don't need #synthesize anymore and there is a new shortcut for NSArray. Here is how your classes should look:
ViewController.h
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *swishImage;
#property (strong, nonatomic) IBOutlet UIButton *swishButton;
#end
ViewController.m
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *swishArray = #[
[UIImage imageNamed:#"Orange_dot.png"],
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
];
self.swishImage.animationImages=swishArray;
self.swishImage.animationDuration = 1;
self.swishImage.animationRepeatCount = 0;
}
- (IBAction)swish:(id)sender {
if (self.swishImage.isAnimating) {
[self.swishImage stopAnimating];
[self.swishButton setTitle:#"Swish" forState:UIControlStateNormal];
} else {
[self.swishImage startAnimating];
[self.swishButton setTitle:#"Searching" forState:UIControlStateNormal];
}
}
#end
Then just select your image view and go to the Connections Inspector. You should see a section titled Referencing Outlets, make sure that swishImage is connected to your view controller.

Why can't I add a UIScrollView to a UIImageView (with it working properly)

I'm working on an app. Here I describe a simplified version of a strange problem I am experiencing.
I have a storyboard created View Controller with a UIImageView also created in the storyboard.
I then have the following h and m files which aim to add a UIScrollView to the UIImageview and give the scrollview a container.
h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (nonatomic, strong) UIScrollView* scrollView;
#property (nonatomic, strong) UIView* container;
#end
m file:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed: #"new_phots_fake_port.png"];
//Add the image to the imageView I created in the Storyboard
[_imageView setImage:image];
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(60.0, 70.0, 522.0, 100.0)];
[_scrollView setBackgroundColor:[UIColor yellowColor]];
// Set up the container view to exist inside the scrollview:
CGSize containerSize = CGSizeMake(5000.0f, 730.0f);
_container = [[UIView alloc] initWithFrame:(CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=containerSize}];
_container.backgroundColor = [UIColor redColor];
// Tell the scroll view the size of the contents
self.scrollView.contentSize = containerSize;
[_scrollView addSubview:_container];
[_imageView addSubview:_scrollView]; //This is what I want but doesn't allow scrolling
//[self.view addSubview:_scrollView]; //This allows scrolling but makes the imageView and Scrollview siblings. I need scrollview to be a child of imageview
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
So, the scrollview cannot seem to be added to the imageview (and function correctly). Why? What am I doing wrong?
Strangely, I also didn't use either of the delegate methods viewForZoomingInScrollView or scrollViewDidZoom. I'm not sure why these were not needed.
You need to set userInteractionEnabled on the UIImageView
_imageView.userInteractionEnabled = YES;

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];