I created Custom UIView with bunch of labels. label1, label2,
UIView *testContentView = [[[UINib nibWithNibName:#"testContentView" bundle:nil] instantiateWithOwner:nil options:nil] objectAtIndex:0];
How do I access the label and setting text ?
You need to define them on your interface.
#interface TestContentView : UIView
#property (weak, nonatomic) IBOutlet UILabel *label1;
#property (weak, nonatomic) IBOutlet UILabel *label2;
#end
And then...
testContentView.label1.text = #"foo";
testContentView.label2.text = #"bar";
Edit
Added IBOutlet to the properties since you are using a NIB, you will also need to wire these up in Interface Builder.
In order to access your custom properties, you need to cast the UIView to a TestContentView.
TestContentView *testContentView = (TestContentView *)[[[UINib nibWithNibName:#"testContentView" bundle:nil] instantiateWithOwner:nil options:nil] objectAtIndex:0];
Related
In my app I have a custom Google Map pin marker designed in a Nib file. Part of the pin marker will display an estimated arrival time.
Here is how I am loading the Nib, and attempting to set a custom time:
self.markerPinFromNib = [[[NSBundle mainBundle] loadNibNamed:#"PinWithTimeView" owner:self options:nil] firstObject];
self.markerPinFromNib.estTime.text = #"20";
When I run this, I get an error:
-[UIView estTime]: unrecognized selector sent to instance
PinWithTimeView.h
#import <UIKit/UIKit.h>
#interface PinWithTimeView : UIView
#property (nonatomic, weak) IBOutlet UIImageView *rotateCircle;
#property (nonatomic, strong) IBOutlet UILabel *estTime;
#end
Can someone point out what I'm doing wrong?
In your PinWithTimeView.h
#interface PinWithTimeView : UIView
#property (nonatomic, weak) IBOutlet UIImageView *rotateCircle;
#property (nonatomic, weak) IBOutlet UILabel *estTime;
-(id)initWithEstTime:(NSString*)time;
#end
In your PinWithTimeView.m
-(id)initWithEstTime:(NSString*)time{
self = [super init];
if (self) {
self = [[[NSBundle mainBundle] loadNibNamed:#"PinWithTimeView" owner:self options:nil] objectAtIndex:0];
self.estTime.text = time;
}
return self;
}
In your controller
self.markerPinFromNib = [[PinWithTimeView alloc]initWithEstTime:#"20"];
You should convert the instance from nib to PinWithTimeView in force. Like this:
((PinWithTimeView *)self.markerPinFromNib).estTime.text = #"20";
Because loadNibNamed:owner:options: will return a array include UIView instances.
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.
I'm using a combination of XCTest and OCMock for testing an iOS application. I'm using a UITableViewController to present a series of prototype cells which I would like to write some tests for. The cell itself is in a storyboard so I don't believe I can instantiate it from a nib.
Is the only option to use the viewController which uses the cell to instantiate it?
The custom cell class I'm using has a number of 'IBOutlets' connected to the prototype on the storyboard. The cell class looks something like this:
#interface QRFeedAdCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIImageView *mainImageView;
#property (strong, nonatomic) IBOutlet UIImageView *blurredImageView;
#property (strong, nonatomic) IBOutlet UILabel *titleLabel;
#property (strong, nonatomic) IBOutlet UIButton *someButton;
#property (strong, nonatomic) IBOutlet UILabel *someLabel;
#property (strong, nonatomic) IBOutlet UILabel *anotherLabel;
#property (nonatomic) BOOL isBusy;
#end
I've tried instantiating the cell using [[QRFeedAdCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"feedAdCell"]; but that will load the cell with all of the properties set to nil.
I've also tried registering the cell, but the tests also fail:
id mockTableView = [OCMockObject niceMockForClass:[UITableView class]];
[mockTableView registerClass:[QRFeedAdCell class] forCellReuseIdentifier:#"feedAdCell"];
QRFeedAdCell *cell = [mockTableView dequeueReusableCellWithIdentifier:#"feedAdCell"];
XCTAssertNotNil(cell, #"");
XCTAssertNotNil(cell.mainImageView, #"");
You can't.
The only way to test it is to instantiate the storyboard, then the view controller, then the cell itself, and then test the properties you set in the Interface Builder.
You can instantiate programmatically but first you need to register it by calling
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cellId"];
Then you can do custom styling to the cell or whatever you usually do in the storyboard like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
// create and add a label
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 155, 21)];
label.text = #"text";
[cell addSubview:label];
...
}
This is working for me in a basic way. I havent gotten viewwillappear to run yet tho.
ViewdidLoad runs when you call .view on _vc.
#property (nonatomic, strong) Edit_ProfileVC *vc;
#property (nonatomic, strong) UIView *view;
#property (nonatomic) NSMutableDictionary *params;
UIStoryboard *mainSB = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
_vc = [mainSB instantiateViewControllerWithIdentifier:#"EditProfileVC"];
_vc.userData = [[EditUserTableDataSource alloc] initDataSourceWithJSON:self.params];
_view = _vc.view;
XCTAssertNotNil(_view, #"the view is not loading properly");
I have a custom UIView which was build with xib that have a file owner called CustomModuleUIView which contains labels and buttons . I have called this custom view in my Rootviewcontroller and I succeeded to display it using initWithCoder method. The problem is that I can't change the default text of UILabel neither from customMouleUIView nor from the root ViewController. I found example that tells me to do custom initialisation in in initWithCoder but it doesn't work for me and nothing changes and without any error it displays the default text.
This is my custom UIView xib
This is my root view controller
This is my code oh custom UIView .h
#import <UIKit/UIKit.h>
#interface ModuleCustomUIView : UIView
-(void) setup;
#property (weak, nonatomic) IBOutlet UIImageView *_moduleIcon;
#property (retain, nonatomic) IBOutlet UILabel *_moduleName;
- (IBAction)openDemo:(id)sender;
- (IBAction)close:(id)sender;
#property (weak, nonatomic) IBOutlet UIImageView *_moduleImage;
#property (strong, nonatomic) IBOutlet UILabel *_positionLabel;
#end
code of .m , i use setup method to init my UIView because I couldn't call
[[NSBundle mainBundle] loadNibNamed:xib owner:self options:nil] ;
inside initWithCoder that causes infinite loop .
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self)
{
}
return self;
}
-(void) setup
{
NSString *xib= #"CustomUIView";
NSArray *array=[[NSBundle mainBundle] loadNibNamed:xib owner:self options:nil] ;
UIView *view =[array objectAtIndex:0];
//code that doesn't work
[_positionLabel setText:#"hello world"];
//
[self addSubview:view];
}
this is my root view controller .h
- (void)viewDidLoad
{
[super viewDidLoad];
[_moduleCustomView setup];
[self.view addSubview:_moduleCustomView];
//code doesn't work
[_moduleCustomView setText:#"hello world"];
}
even in the did load I can't change the text
I have found my mistake , it's about file owner , i have change it in the inspector but by selecting the uiview and not te file's owner , i change NSObject to my class name and reconnect the label .
I guess the Files Owner attribute should be your 'root viewcontroller'.