I'm newbie in the iOS development and I'm working in a projecte that it uses iOS5 and Storyboarding. I would like to create a reusable component, like a button, with a custom view (inside the button there will be some images and labels, it will be a big button), to create some of them in the same view of a Storyboard.
So I've created a XIB file (ItemClothes.xib) with a UIButton and inside of it some UIImagesViews and a UILabel. Then I've created a subclass of UIButton (UIItemClothes.h and UIItemClothes.m), with properties for UIImageViews and UILabel components.
UIItemClothes.h
#import <UIKit/UIKit.h>
#import "SCClothes.h"
#interface UIItemClothes : UIButton
#property (nonatomic, strong) IBOutlet UIImageView *imageClothes;
#property (nonatomic, strong) IBOutlet UIActivityIndicatorView *loadingImage;
#property (nonatomic, strong) IBOutlet UIImageView *seasonIconClothes;
#property (nonatomic, strong) IBOutlet UIImageView *categoryIconClothes;
#property (nonatomic, strong) NSString *idClothes;
#property (strong, nonatomic) IBOutlet UILabel *lblProva;
#end
UIItemClothes.m
#import "UIItemClothes.h"
#implementation UIItemClothes
#synthesize imageClothes = _imageClothes;
#synthesize loadingImage = _loadingImage;
#synthesize seasonIconClothes = _seasonIconClothes;
#synthesize categoryIconClothes = _categoryIconClothes;
#synthesize idClothes = _idClothes;
#synthesize lblProva = _lblProva;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:#"ItemClothes" owner:self options:nil] objectAtIndex:0]];
}
return self;
}
#end
Then in the .XIB file I've set the class of UIButton as UIItemClothes, and make the relationships between XIB's UI components and my class properties.
So, after that, in the Storyboard, in the ViewController of one view I've written this code:
UIItemClothes *item = [[UIItemClothes alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 200.0)];
item.lblProva.text = #"test!";
[item.categoryIconClothes setImage:iconCategory];
item.seasonIconClothes.image = iconSeason;
[cell addSubview:item];
As you see, this component will be inside a TableViewCell, and the idea is to put more components (UIItemClothes) inside of it.
The problem is that the component is drawed but any outlet is set as I do in the code above.
Can anyone help me?
Thanks!
well, the problem has been resolved... Instead of having a custom subclass of UIButton, there will be needed a ViewController with all Outlets. Then in the other ViewController (StoryBoard) is initialized this new ViewController
Related
The problem is View is loaded but the inner elements are not loaded or did not appear why?
the xib image is:
and the corresponding .h is:
#import <UIKit/UIKit.h>
#interface DownloadView : UIView
#property (strong, nonatomic) IBOutlet UIView *view;
#property (weak, nonatomic) IBOutlet UILabel *downloadFilename;
#property (weak, nonatomic) IBOutlet UILabel *downloadpercentage;
#property (weak, nonatomic) IBOutlet UIProgressView *downloadprogressBar;
#property (weak, nonatomic) IBOutlet UIButton *downloadCancel;
#end
.m file is:
#import "DownloadView.h"
#implementation DownloadView
-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
[[NSBundle mainBundle] loadNibNamed:#"DownloadView" owner:self options:nil];
[self addSubview:self.view];
}
return self;
}
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
[[NSBundle mainBundle] loadNibNamed:#"DownloadView" owner:self options:nil];
[self addSubview:self.view];
}
return self;
}
The calling file is:
polygonView = [[DownloadView alloc]initWithFrame:CGRectMake(0, height-170, width, 100)];
polygonView.downloadFilename.text = #"Initiating Download...";
[polygonView.downloadprogressBar setProgress:0];
polygonView.downloadpercentage.text = #"0%";
[window addSubview:polygonView];
What is the Problem ?
Debugger update:
The output is:
Unfortunately you can't create custom UIView like this, it will not work. I use different way for reusable custom components which is:
Create new view controller in the storyboard, change its frame, and customize it.
Give it an identifier
In all places you want to use in storyboard, just create Container view and embed your custom view controller.
If you want to use it programmatically. Just instantiate it from storyboard with the identifier. Resize its view frame and add it as a subview.
I am still learning interface builder.
I created a xib containing a button, a progress bar and a spinner. Lets call this xib MyToolbar.xib. I created classes for that xib (MyToolbar.h and .m). Inside the xib, I set the toolbar’s class to MyToolbar. Inside the xib I set File’s Owner to MyToolbar. I connected outlets to all elements and put them on the header.
The class header is this:
#import <UIKit/UIKit.h>
#interface MyToolbar : UIToolbar
#property (weak, nonatomic) IBOutlet UIButton *button;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
#property (weak, nonatomic) IBOutlet UIProgressView *progressBar;
#end
this is the implementation
#import “MyToolbar.h"
#implementation MyToolbar
- (id)init {
self = [super init];
if (self) {
self = [[[NSBundle mainBundle] loadNibNamed:#"MyToolbar"
owner:self
options:nil]
objectAtIndex:0];
}
return self;
}
Now I create the object on the main class
MyToolbar *toolbar = [[MyToolbar alloc] init];
at this point, toolbar is not nil but toolbar.button, toolbar.progessBar and toolbar.spinner are all nil.
I know the elements are not instantiated unless you display them.
Is there a way to make this work without displaying the object?
Did you connect the views to File's owner outlet? Try to remove the File's owner or connections and connect the views to MyToolbar.h outlets. I tried and it's working.
Writing my first iphone app through this tutorial--I have a custom UIView with the method showDie and I have two UIView elements on my storyboard that I've hooked up to my ViewController. However, both the UIView elements have the error message "No visible #interface for 'UIView' declares the selector 'showDie'. I think that's because the UIViews aren't subclassing XYZDieView, but when I control-clicked from my Storyboard, only UIView appeared in the dropdown--no XYZDieView. I tried just changing the text manually in the ViewController.h, but that didn't work (I didn't think it would). Am I on the right track? How do I use my subclass? (xcode 5)
XYZDieView.m
-(void)showDie:(int)num
{
if (self.dieImage == nil){
self.dieImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
[self addSubview:self.dieImage];
}
NSString *fileName = [NSString stringWithFormat:#"dice%d.png", num];
self.dieImage.image = [UIImage imageNamed:fileName];
}
XYZViewController.h
#import <UIKit/UIKit.h>
#import "XYZDieView.h"
#interface XYZViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *sumLabel;
#property (strong, nonatomic) IBOutlet UIButton *rollButton;
#property (strong, nonatomic) IBOutlet UIView *leftDieView;
#property (strong, nonatomic) IBOutlet UIView *rightDieView;
#end
XYZViewController.m
#import "XYZViewController.h"
#import "XYZDiceDataController.h"
#interface XYZViewController ()
#end
#implementation XYZViewController
- (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.
}
- (IBAction)rollButtonClicked:(UIButton *)sender {
XYZDiceDataController *diceDataController = [[XYZDiceDataController alloc] init];
int roll = [diceDataController getDiceRoll];
int roll2 = [diceDataController getDiceRoll];
[self.leftDieView showDie:roll];
[self.rightDieView showDie:roll2];
int sum = roll + roll2;
NSString *sumText = [NSString stringWithFormat:#"Sum is %i", sum];
self.sumLabel.text = sumText;
}
#end
Yes you're right, the problem is subclassing. In order to have a view conform to a subclass in the interface builder you need to
Click on the UIView in your storyboard
Open the right inspector panel
Click on the third tab for identity inspector
Add your class
Then try to connect it to your ViewController again.
Edit: Afterwards you may need to cast XYZDieView myView = (XYZDieView*)leftDieView;
I would like to modify the text property of a UILabel (nameLbl) but don't know what i am wrong.
I have 2 Views, the first is a ViewController, the second is ProfileViewController. The ProfileViewController fill some field of user profile this data are passed to ViewController and showed in UIlabel.
The issue is I can't show the datas in the ViewController.
What am I get wrong?
---ViewController.h---
#interface ViewController : UIViewController
{
IBOutlet ViewController *profile;
IBOutlet UILabel *nameLbl, *celLbl, *cfLbl;
IBOutlet UITextField *nameTF;
}
#property (nonatomic, retain) IBOutlet ViewController *profile;
#property (retain, nonatomic) IBOutlet UILabel *nameLbl, *celLbl, *cfLbl;
#property (nonatomic, retain) IBOutlet UITextField *nameTF;
-(void) setUser: (NSString *) name:(NSString *) cel:(NSString *) cf;
#end
---ViewController.m---
#synthesize nameLbl, celLbl, cfLbl;
-(void) setUser:(NSString *)name:(NSString *)cel:(NSString *)cf
{
nameLbl = [[UILabel alloc] init];
[nameLbl setText:name];
}
this is the connection inspector
https://drive.google.com/file/d/0Bz7WcQmZNuFLMWt3QUo1Tk5XUW8/edit?usp=sharing
Remove
nameLbl = [[UILabel alloc] init];
from your code it seems that the nameLbl UILabel has already been initialized from nib, and you are creating a new memory reference, so its not working.
I can't figure out what is happening with my custom UITableViewCell.
The header file:
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIImageView *imageView;
#property (nonatomic, strong) IBOutlet UILabel *personName;
#property (nonatomic, strong) IBOutlet UILabel *detailedTextLabel;
#property (nonatomic, strong) IBOutlet UILabel *amountLabel;
#end
The implementation file:
#import "CustomCell.h"
#implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {}
return self;
}
There is also a XIB file. The layout is an image view on the left and text and detailed text on the right.
Here is the problem. These custom cells are used in a UITableViewController. When I select one of the UITableViewCell, the imageView would shift to the right instead of being in the center when it initially gets loaded.
The most confusing thing is that the problem goes away if I add #synthesize to the implementation. As far as I know, the synthesize adds setter and getters however, in my implementation file, those properties are not set anywhere. They are an IBOutlet property so that my XIB can connect to them. Please tell me what might be going on?
Thanks!
There's no needs to synthesize the outlets. Seems like there are autolayouts enabled on xib file. Just disable them and try again.