Issue Subclassing UIView - iphone

I've created my own custom view, with its own header and main file and corresponding nib (.xib):
The header file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface PointsBarView : UIView
{
IBOutlet UIView *pointsBarView;
IBOutlet UIView *pointsCounterView;
IBOutlet UILabel *pointsTotalLabel;
UIImageView *handImageView;
UIImageView *powerBarOutlineImageView;
}
#property (nonatomic, retain) IBOutlet UIView *pointsCounterView;
#property (nonatomic, retain) IBOutlet UIView *pointsBarView;
#property (nonatomic, retain) IBOutlet UILabel *pointsTotalLabel;
#property (nonatomic, retain) IBOutlet UIImageView *handImageView;
#property (nonatomic, retain) IBOutlet UIImageView *powerBarOutlineImageView;
#end
I'm synthesizing everything in the main, and then in another UIViewController class I'm trying to load this view. I set up its property:
#property (nonatomic, assign) IBOutlet PointsBarView *pointsBarView;
And am adding as so:
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"PointsBarView" owner:self options:nil];
pointsBarView = [nibViews objectAtIndex: 0];
[[self view] addSubview:pointsBarView];
How do I access those subviews within my NIB? Do they need to be embedded within the pointsBarView? (pointsBarView references the main view of the NIB, and all the other views are within the pointsBarView). Should they each be a separate piece of the NIB and I need to call addSubview for each one to display?
I should note that if I do NOT connect any of the properties in PointsBarView, the view displays just fine with the code in my UIViewController class. But I want to be able to interact with each view and change properties accordingly. Any help would be great!

The general rule of thumb is: if you load it from code, you connect it up in code.
conversely:
If you instantiate in IB, you can connect outlets and actions in IB.
Here you are loading the view in code, so you have to manually connect them.
If you want to be able to connect stuff in IB add a UIVIew in IB and change the subclass to PointsBarView. IB will magically read the PointsBarView.h file and you should be able to connect outlets, targets and actions.

Related

uiscrollview in uiview not scrolling

I am using the storyboard to create a UIView that contains a UIScrollView that has many child items in it. these child items consist of a UIImageView that I am using as a background image for the UIScrollView, a series of UILabels that I populate programmatically, and a series of UITableViews that I populate with data obtained from a called set of library classes. I want all of this in my UIScrollView so the User can scroll through all of the information without having multiple views being displayed. I have browsed through a lot of postings here and have used a lot of the suggestions, but have been unable to successfully have the view scroll and allow the user to see all the data I'm attempting to present.
Here's a screen shot of the Storyboard followed by a shot of the attribute inspector for my UIScrollView
I'll also provide the .h and .m files
weatherController.h
#import <UIKit/UIKit.h>
#import "WeatherParser.h"
#import "WeatherLocation.h"
#import "WeatherImg.h"
#import "WeatherWind.h"
#import "ForcastDay.h"
#import "ForecastItem.h"
#import "Condition.h"
#import "Atmo.h"
#import "Astro.h"
#class WeatherParser;
#class WeatherParserDelegate;
#class WeatherLocation;
#class WeatherImg;
#class WeatherWind;
#class ForcastDay;
#class ForecastItem;
#class Condition;
#class Atmo;
#class Astro;
#interface weatherController : UIViewController <UITableViewDataSource,UITableViewDelegate,WeatherParserDelegate>{
WeatherParser * _rssParser;
bool loadingEvents;
}
#property (nonatomic, retain) WeatherParser * rssParser;
#property bool loadingEvents;
#property (retain, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet UILabel *cityLabel;
#property (weak, nonatomic) IBOutlet UILabel *state_countryLabel;
#property (weak, nonatomic) IBOutlet UILabel *currHighLabel;
#property (weak, nonatomic) IBOutlet UILabel *currLowLabel;
#property (weak, nonatomic) IBOutlet UILabel *currTempLabel;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UIImageView *logoImageView;
#property (weak, nonatomic) IBOutlet UILabel *logoLabel;
#property (weak, nonatomic) IBOutlet UITableView *forecastTableView;
#property (weak, nonatomic) IBOutlet UITableView *atmoTableView;
#property (weak, nonatomic) IBOutlet UITableView *windTableView;
#property (weak, nonatomic) IBOutlet UITableView *astroTableView;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
#property (nonatomic, retain) NSMutableArray *forecastDays;
#property bool logoSet;
#end
and here's my weatherController.m file. I'm going to only add the viewDidLoad method which is the only method containing code regarding my UIScrollView.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_scrollView.delegate = self;
// self.scrollView.frame = CGRectMake(0, 0, 320.0f, 480.0f);
self.scrollView.contentSize =CGSizeMake(320.0F, 480.0F); //(320, 1210)];
[_scrollView setScrollEnabled:YES];
}
I would appreciate any help regarding what it is I'm either doing wrong or missing. If I set up my frame and contentSize to the following:
self.scrollView.frame = CGRectMake(0, 0, 320.0f, 480.0f);
self.scrollView.contentSize =CGSizeMake(320.0F, 1210.0F);
I do get the UIScrollView to scroll, but the image for the background is only the size of the frame, and none of the rest of the child content on the UIScrollView is displayed. It seems like it's allowing me to scroll but I'm only able to view the content that is viewable within the frame.
Again, thank you in advance for any help offered.
As the comments are suggesting, it's generally a bad idea to put a UITableView within a UIScrollView. I won't be too hard on you though, because there is a time and place where it is an acceptable solution. I'll let you judge if this time is now or not.
For reasons I still don't fully understand, UIScrollView behaves more like you expect it to if you enclose the entire contents in a single UIView that is as big as you want the UIScrollView to scroll.

iPhone/iOS: Subclassing UITableViewCell two times --> cannot reference properties of parentclass in InterfaceBuilder

I want to use UITableViewCells within my application which have an image, and that image is downloaded asynchronously. Too accomplish that and to make sure that I dont have to write the same code several times within my application I subclassed UITableViewCell like so:
#import <UIKit/UIKit.h>
#interface ImageCell : UITableViewCell {
UIImageView* imageView;
}
#property (nonatomic, retain) UIImageView* imageView;
#end
Everytime I need a Cell with an image I would like to subclass the ImageCell like so:
#import <UIKit/UIKit.h>
#import "ImageCell.h"
#interface StoreCell : ImageCell {
UILabel* streetAddress;
UILabel* retailerName;
UILabel* distance;
}
#property (nonatomic, retain) IBOutlet UILabel* streetAddress;
#property (nonatomic, retain) IBOutlet UILabel* retailerName;
#property (nonatomic, retain) IBOutlet UILabel* distance;
#end
However this doesnt seem to work. Since StoreCell is subclassing ImageCell I cant reference the property "imageView" anymore within the InterfaceBuilder.
Am I missing something here? Is this subclassing-scheme I'm trying to accomplish not meant to be in Objective-C / iPhone OS?
I think you need to tell interface builder about it using IBOutlet ... so
#property (nonatomic, retain) IBOutlet UIImageView* imageView;

UIViewController IBOutlets are nil

I have an UIViewController class with two labels and a UIImageView set as IBOutlets, and I have this outlets connected in my xib, I have double checked they are connected properly, however when I check the their value in the debugger they are 0x0 so I cant change them programatically. Any ideas on what I might be doing wrong.
Heres the header file of my code:
#import <UIKit/UIKit.h>
#interface PlateDetailViewController : UIViewController {
IBOutlet UIImageView *image;
IBOutlet UILabel *price;
IBOutlet UILabel *description;
}
#property (nonatomic, retain)IBOutlet UIImageView *image;
#property (nonatomic, retain)IBOutlet UILabel *price;
#property (nonatomic, retain)IBOutlet UILabel *description;
#end
Your outlets won't get set until the view controller's view is actually instantiated, which in your case is probably happening shortly after initWithNibName:bundle:—at which point they'll still be nil. Any setup you do that involves those outlets should be happening in your view controller's -viewDidLoad method.

Do I need to create variables and link IBOutlet for every UIVIew?

I have a View Controller that is swapping UIView objects in and out. There is the potential to have hundreds of different views, each with their own behaviors.
Within my current MainWindow.xib file I currently have:
File's Owner UIApplication
First Responder UIResponder
AppDelegate AppDelegate
-Cover Cover
Window UIWindow
Table of Contents TableOfContents
page1 Page1
page2 Page2
page...n Page...n
The AppDelegate declares the window and the viewController. It's pretty basic.
MainViewController.h
#import <UIKit/UIKit.h>
#class TableOfContents, Page1;
#interface MainViewController : UIViewController {
TableOfContents *tableOfContents;
Page1 *page1;
Page2 *page2;
Page...n *page...n;
}
#property (nonatomic, retain) IBOutlet TableOfContents *tableOfContents;
#property (nonatomic, retain) IBOutlet Page1 *page1;
#property (nonatomic, retain) IBOutlet Page2 *page2;
#property (nonatomic, retain) IBOutlet Page...n *page...n;
-(IBAction)funcGoToPage:(id)sender;
#end
MainViewController.m
#import "MainViewController.h"
#import "TableOfContents.h"
#import "Cover.h"
#import "Page1.h"
#import "Page2.h"
#import "Page...n.h"
#implementation MainViewController
#synthesize page1, page2, page...n tableOfContents;
#synthesize pageID, pagesPathFile, pagesPath;
-(IBAction)funcGoToPage:(id)sender{
//[[self view] removeFromSuperview];
[self.view addSubview:self.tableOfContents];
}
The corresponding UIView classes are pretty bare at the moment so I'll refrain from posting them.
Right now funcGoToPage is just bringing up tableOfContents. Eventually I'll have it go different places depending on what was clicked.
Currently each page is set up as an IBOutlet and linked from the MainViewController to the appropriate UIView in Interface Builder. Done this way each page will have to be set up as a variable and linked to in IB creating a hubub of variables, outlets and connections.
My question is: Is there a way to create these connections on the fly so that I can swap them in using my funcGoToPage function without setting them up as an IBOutlet?
When a nib is loaded all of its content is loaded. If you have lots of views in one nib you'll quickly run out of memory.
I would put each page in a seperate nib and then load the nib when required:
[[NSBundle mainBundle] loadNibNamed:#"nibNameWithoutExtension" owner:self options:nil];
For this to work:
add an IBOutlet, eg newPage, to whatever self refers to
set the File Owner in nibNameWithoutExtension to whatever self refers to
join the view in nibNameWithoutExtension to the newPage outlet of File Owner

iPhone UIImageView Array

So I'm declaring a NSMutableArray to hold 5 UIImageViews.
.h file:
#interface ImageDisplay : UIViewController {
IBOutlet UIImageView *img1;
IBOutlet UIImageView *img2;
IBOutlet UIImageView *img3;
IBOutlet UIImageView *img4;
IBOutlet UIImageView *img5;
NSMutableArray *imageHolderArray;
}
#property (nonatomic, retain) IBOutlet UIImageView *img1;
#property (nonatomic, retain) IBOutlet UIImageView *img2;
#property (nonatomic, retain) IBOutlet UIImageView *img3;
#property (nonatomic, retain) IBOutlet UIImageView *img4;
#property (nonatomic, retain) IBOutlet UIImageView *img5;
#property (nonatomic, retain) IBOutlet NSMutableArray *imageHolderArray;
#end
In the .m file:
//All objects are synthesized, just easier not to crowd the screen
- (void)viewDidLoad {
[super viewDidLoad];
imageHolderArray = [[NSMutableArray alloc] initWithObjects: img1,img2,img3,img4,img5,nil];
NSLog(#"imageHolderArray count: %i",[imageHolderArray count]); //Returns count of 1
}
So my question is, why is this happening? Why isn't it picking up all the objects in the Array? I'm not well versed in Objective-C programming so I'd appreciate it if someone could clue me in here. Thank you.
Because you didn't wire the IBOutlets to their views in Interface Builder. Looks like you probably wired img1, but didn't wire img2, so img2 is nil, which marks the end of your list of objects for -initWithObjects: even if later outlets are wired.