I need to create my own UIView class and it is not something I have had to do. I created the class, then laid out the small view in IB (it's just a few labels that i will later need to add data to ). but now im stuck on how to actually put an instance of it in my main view. Can someone point me in the direction of a good tutorial? The closest thing I have done to this is creating a custom tableViewCell.
DataTagViewController.m:
- (id)initWithNibNamed:(NSString *)DataTagViewController bundle:bundle {
if ((self = [super initWithNibName:DataTagViewController bundle: bundle])) {
// Custom initialization
}
return self;
}
MapView.m:
DataTagViewController *dataTag = [[DataTagViewController alloc] initWithNibNamed:#"DataTagViewController" bundle:nil];
[theMap addSubView: dataTag.view]; <<< this line causes the crash (theMap is a UIView)
I now get this runtime error when adding the subview:-[UIView addSubView:]: unrecognized selector sent to instance 0x470f070'
2010-06-06 21:22:08.931
UIViewController is not a view, but controls a view. If your DataTagViewController class extends UIViewController, then you'll want to add it's view, not the class itself:
[theMap addSubView:dataTag.view];
Also, do you have a DataTagViewController.xib file created that has your view in it? If you don't, you'll need to create one and use the UIViewController's initWithNibName:bundle method. Otherwise, you'll have to implement the loadView method instead to provide your own view via code.
Edit
Your init function is using the name of your class as a variable. That probably won't work. Use the default sigature:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
}
}
If you aren't doing anything beyond the init function, you don't need to implement this method. Your alloc/init statement is enough.
For a good tutorial, read the View Controller Programming guide in the docs.
What is the parent class of DataTagViewController? You say you need to create "my own UIView class", but your example suggests that you actually want to create UIViewController subclass. initWithNibNamed: is UIViewController method. If your parent is UIView, then "unrecognized selector" makes sense.
Related
I am working with the library KYCircleMenu. You can find it over here. I am also working with storyboards. I made a Class MenuViewController that is derived from KYCircleMenu
#interface MenuViewController : KYCircleMenu
Next I have implemented my initWithCoder like this.
- (id)initWithCoder:(NSCoder*)aDecoder
{
NSLog(#"called");
if(self = [self initWithButtonCount:kKYCCircleMenuButtonsCount
menuSize:kKYCircleMenuSize
buttonSize:kKYCircleMenuButtonSize
buttonImageNameFormat:kKYICircleMenuButtonImageNameFormat
centerButtonSize:kKYCircleMenuCenterButtonSize
centerButtonImageName:kKYICircleMenuCenterButton
centerButtonBackgroundImageName:kKYICircleMenuCenterButtonBackground])
{
}
return self;
}
And finally I have implemented a method from the KyCicrleMenu RunButtonActions. This method tells me what button is pressed in the menu. So in this method I am trying to do a segue to another viewcontroller. I am doing it like this.
NSLog(#"tag is %d",[sender tag]);
[self performSegueWithIdentifier:#"showNews" sender:self];
(The log gives me the button tag from the button that is pressed).
For some reason or another I keep getting this error.
Receiver (<MenuViewController: 0x1cd7cf50>) has no segue with identifier 'showNews''
Here is a screenshot from my storyboard.
Can anybody help me with this annoying problem?
Kind regards
- (id)initWithCoder:(NSCoder*)aDecoder
{
NSLog(#"called");
if(self = [self initWithButtonCount:kKYCCircleMenuButtonsCount
menuSize:kKYCircleMenuSize
buttonSize:kKYCircleMenuButtonSize
buttonImageNameFormat:kKYICircleMenuButtonImageNameFormat
centerButtonSize:kKYCircleMenuCenterButtonSize
centerButtonImageName:kKYICircleMenuCenterButton
centerButtonBackgroundImageName:kKYICircleMenuCenterButtonBackground])
{
}
return self;
}
Here, you are doing nothing with the aDecoder object - this contains all of the information from the storyboard (including the segue). Instead you are creating a brand new object, ignoring anything you have set up in the storyboard.
I've had a quick look at the repository and it doesn't seem to be tailored towards use in a storyboard - it implements its own loadView method, it has a designated initialiser and so on. You'd have to play around with it to set those properties after calling [super initWithCoder:aDecoder];, perhaps by pulling out the setup code from the designated initialiser and putting it into a separate method.
In my UIViewController named MainViewController, I have a reference to another UIViewController named SubViewController. It is defined as follows:
#class SubViewController;
#interface MainViewController : UIViewController <UIScrollViewDelegate> {
SubViewController * _subViewController;
}
In the initWithNibName:bundle: method of my MainViewController, I initialize my SubViewController as follows:
#pragma mark - Init
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; {
if((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])){
_subViewController = [[SubViewController alloc] initWithNibName:#"SubViewController" bundle:nil[;
// Forces the view to load, in an attempt to speed up the adding of the subview.
UIView * view = _subViewController.view;
view.alpha = 1.0f;
}
return self;
}
The viewDidLoad method of the SubViewController does get called, and everything seems to be loaded, but when I add the SubViewController as a subview:
- (IBAction)showButtonPressed:(UIButton *)aButton; {
[self.view addSubview:_subViewController.view];
}
The app slows down for a couple of seconds, and then the subview is added and everything is fine. The strange thing is, when I remove the subview and try to re-add it again, there is no delay!
I assume the issue is a loading one, but I can't find any documentation on how to solve this.
Can anyone explain what is causing this slow down? Thanks!
your code its not complete !!
i try to take your code and make new project -ARC- and its fain to me no delay at all
try to use Instruments to find whats happen
I never had issues like that. since you are saying if you don't load the second view it works faster. check to see what is in the viewWillAppear and viewDidAppear for the secondViewController
I'm developing an iOS 4 application and I have developed some classes that I want to use in others projects.
One of this classes, called MapViewController, is a UIViewController subclass. This class uses a XIB file that I've created with interface builder.
I'm wondering if a use MapViewController in another project as a super class from a new class, How can I use it associated XIB?
I want to reuse MapViewController and its XIB, but I don't know if I have to do something special with the XIB file.
I don't know how to explain this. If you need more details, please tell me.
UPDATE:
I want to create a new class that inherit from MapViewController, like this:
...
#interface NewMapViewController : MapViewController {
...
And, now if I want to continue using the same XIB (the one from MapViewController), what must I do?
Since you are gonna inherit from MapViewController, your MapViewController becomes the super class. And you also have MapViewController.xib. It seems pretty straightforward to me if you use the initializer for NewMapViewController
NewMapViewController.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
NSLog(#"Subclass initWithNibName called");
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Initialize your NewMapViewContoller like:
//Nib of super class is MapViewController
NewMapViewController *nmapController = [[NewMapViewController alloc] initWithNibName:#"MapViewController" bundle:[NSBundle mainBundle]];
I make all my controllers in code and most of the GUI too. Some GUI's I make with IB. I then set the file's owner to the viewcontroller and drag an connection from the file's owner to the view. But initWithNibName confuses me...
I am override the designated initializer to this
- (id)init {
[super initWithNibName:nil bundle:nil];
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
return [self init];
}
Why do I not need to set which nib the viewController shall use in the init-initalizer? Because it works without. I thought I must use [super initWithNibName:#"SomeNib" bundle:nil];
In the init-initalizer
From docs: If you specify nil for the nibName parameter, you must either override the loadView method and create your views there or you must provide a nib file in your bundle whose name (without the .nib extension) matches the name of your view controller class. (In this latter case, the class name becomes the name stored in the nibName property.) If you do none of these, the view controller will be unable to load its view.
It works without only if your nib name is the same as your controller class name. In that case Apple does some magic. It is generally good form to specify the nib name.
The App Delegate has an outlet property to the view controller, and the view controller is created in the nib.
Althoug the -viewDidLoad method of the view controller gets loaded, it seems that it designated initializer receives no call:
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
NSLog(#"iniwinib");
if (self = [super initWithNibName:nibName bundle:nibBundle]) {
// do stuff
}
return self;
}
I also tried with -init, but this also does not receive a call. No NSLog output. Is there another initializer that I must use in this case?
-initWithCoder: is the initializer in this case (because the object is being deserialized from the NIB), but the routine you actually want here is -awakeFromNib. That's what's called after all the objects in the NIB have been constructed and all the outlets have been wired.
Are you actually calling initWithNibName to create your ViewController somewhere in the code? If not then it will never get called, this method does not get called automatically you must call it to create your viewController from your nib. But you dont need to do call this method because you have already set the ViewController in the nib..