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.
Related
I have a very simple method that allows me to specify the name of a UIButton and then set its title. I previously had the method in my main ViewController which worked fine. But then I have decided to create a new file called CustomMethods.h/m and put all of my methods in there.
As soon as I have moved the method across and #import the header into the main view controller I am getting the error message below
No visible #interface for ViewController declares the selector 'SetTitleOfButtonNamed:withTitle:'
In my CustomMethods file I have created my method as follows:
-(void)setTitleOfButtonNamed:(UIButton *)button withTitle:(NSString *)buttonTitle
{
[button setTitle:buttonTitle forState:(UIControlStateNormal)];
}
In the viewDidLoad of the main ViewController I am trying to call this method and set the button title as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *btnOneTitle = #"Button 1";
[self setTitleOfButtonNamed:buttonOne withTitle:btnOneTitle]; // ERROR OCCURS HERE
}
Before I copied the method into its own file it worked perfectly. Any ideas?
You are still calling setTitleOfButtonNamed on "self" which is the ViewController. You need to call it from the CustomMethods class that implements the method now.
[self setTitleOfButtonNamed:buttonOne withTitle:btnOneTitle];
I have two view Controllers in my project ViewController, SettingsView. Here I am trying to update the ViewController's label, when i click on the SettingsView's back button. NSLog is working fine, but the label is not updating...
Please help me....
SettingsView.m
-(IBAction)backToMain:(id) sender {
//calling update function from ViewController
ViewController * vc = [[ViewController alloc]init];
[vc updateLabel];
[vc release];
//close the SettingsView
[self dismissModalViewControllerAnimated:YES];
}
ViewController.m
- (void)updateLabel
{
NSLog(#"Iam inside updateLabel");
self.myLabel.text = #"test";
}
Could you please tell me whats wrong with my code? Thank you!
You have to implement protocols for that. Follow this:
1) In SettingView.h define protocol like this
#protocol ViewControllerDelegate
-(void) updateLabel;
#end
2) Define property in .h class and synthesis in .m class..
#property (nonatomic, retain) id <ViewControllerDelegate> viewControllerDelegate;
3) In SettingsView.m IBAction
-(IBAction)backToMain:(id) sender
{
[viewControllerDelegate updateLabel];
}
4) In ViewController.h adopt protocol like this
#interface ViewController<ViewControllerDelegate>
5) In viewController.m include this line in viewDidLoad
settingView.viewControllerDelegate=self
Your label is not updating because , you are trying to call updateLabel method with a new instance.
You should call updateLabel of the original instance of viewcontroller from which you have presented your modal view.
you can use a delegate mechansim or NSNotification to do the same.
Delegate mechnaism would be clean. NSNotification is quick and dirty.
You are not exactly calling the correct vc. This is because you are creating a new instance of that class and calling the updateLabel of that instance.
You have a few options.
Either implement it as a delegate callBack (delegate messagePassing, or delegate notification - however you want to call it) to notify that class instance to call the updateLabel method.
Use the original instance VC as a dependency injection into the class that you are on right now, and use that instance to call the updateLabel
Use NSNotifications / NSUserDefaults to communicate between viewControllers and setup a notification system for your actions. This is quite easy, but not really great in the long run.
I would RECOMMEND option 1 (or) option 2.
Simply declare like this in SettingsView class:
UILabel *lblInSettings;// and synthesize it
Now assign like below when you presenting Settings viewController:
settingsVC.lblInSettings=self.myLabel;
Then whatever you update in lblInSettings it will be present in MainView obviously....
no need for any delegate methods or updating methods.
Means if you assign at the time of dismissing like
lblInSettings.text=#"My new value";
then self.myLabel also will be updated.
Let me know if you have any queries?
I have been trying for a while now, but I can't figure out how to integrate InAppSettingsKit in an App, that uses Storyboard and a TabBar.
I've got my tab bar defined in a Storyboard, now I want one tab to have this InAppSettingsKit as the root view. Is this possible after all?
Thanks everyone.
Well, after trying various things, I figured out, that my problem actually was, that I put all the IASK-stuff into a static library (and I had no Settings Bundle). After moving all the code and nibs to the same project as the MainStoryboard, it worked by adding a TableView Controller to my storyboard and settings its custom class to IASKAppSettingsViewController.
Alternatively, if you want button handlers and other custom code, do following:
Create a class derived from UITableViewController
Modify the header file to derive from IASKAppSettingsViewController
<IASKSettingsDelegate> Remove all methods but the initWithCoder and the
settingsViewControllerDidEnd protocol (or make calls to super). This
is so that the default UITableVC code doesn't override IASK
functionality. Be sure to stick self.delegate = self; into the
initWithCoder to get the buttons to work.
//SettingsViewController.h
#import "IASKAppSettingsViewController.h"
#interface SettingsViewController : IASKAppSettingsViewController <IASKSettingsDelegate>
#end
//SettingsViewController.m
// ...
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.delegate = self;
}
return self;
}
#pragma mark -
#pragma mark IASKAppSettingsViewControllerDelegate protocol
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
Set custom class of the table view in storyboard to
your class
I create custom login page by using UIAlerView subclass. Now when i click on button it opens up UIAlertView I want to change the main view based on which button is pressed.
But as all implementation of UIAlerView is in another class though i change the view it doesn't retain that as that class variable doesn't get it's value.
Can anyone please help me with this? I can post the code if required.
Thank you,
Ankita
You can use a custom init method like below for alertView and store the _sender in global or class variable. like
id sender;
- (id)initWithSender:(id)_sender
{
self = [super init];
if (self) {
sender=_sender;
}
return self;
}
from RootVC/bgview initialize alertView as follows and define a method named
-(void) alertIndexSelected:(NSInterger) index;
{
//change the backgound view based on button selected
}
in rootvc/your main view.
alertViewobj =[[alertView alloc] initWithSender:self];
when the button is selected on alertview call the below method, this will notify your rootvc about which index of alert is pressed. use following alertview delegate.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[sender alertIndexSelected: buttonIndex];
}
If you are planning to use delegate methods then I think you need to referrer to some of these links.
How to use custom delegates in Objective-C
How do I create delegates in Objective-C?
http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
I hope this will help you a great deal in understanding delegates.
I'm trying to figure out how I can call a function from another one of my classes. I'm using a RootViewController to setup one of my views as lets say AnotherViewController
So in my AnotherViewController im going to add in on the .h file
#class RootViewController
And in the .m file im going to import the View
#import "RootViewController.h"
I have a function called:
-(void)toggleView {
//do something }
And then in my AnotherViewController I have a button assigned out as:
-(void)buttonAction {
//}
In the buttonAction I would like to be able to call the function toggleView in my RootViewController.
Can someone clarify on how I do this.
I've tried adding this is my buttonAction:
RootViewController * returnRootObject = [[RootViewController alloc] init];
[returnRootObject toggleView];
But I dont think that's right.
You'll want to create a delegate variable in your AnotherViewController, and when you initialize it from RootViewController, set the instance of RootViewController as AnotherViewController's delegate.
To do this, add an instance variable to AnotherViewController: "id delegate;". Then, add two methods to AnotherViewController:
- (id)delegate {
return delegate;
}
- (void)setDelegate:(id)newDelegate {
delegate = newDelegate;
}
Finally, in RootViewController, wherever AnotherViewController is initialized, do
[anotherViewControllerInstance setDelegate:self];
Then, when you want to execute toggleView, do
[delegate toggleView];
Alternatively, you could make your RootViewController a singleton, but the delegate method is certainly better practice. I also want to note that the method I just told you about was Objective-C 1.0-based. Objective-C 2.0 has some new property things, however when I was learning Obj-C this confused me a lot. I would get 1.0 down pat before looking at properties (this way you'll understand what they do first, they basically just automatically make getters and setters).
I tried out the NSNotificationCentre - Works like a charm - Thanks for your reply. I couldn't get it running but the NS has got it bang on.
[[NSNotificationCenter defaultCenter] postNotificationName:#"switchView" object: nil];