i am creating UIButton Programatically.I want a UIViewController to be the target of that button action.How would I do that?.If i click the button navigation will not work.This is my code.please help me anybody.Thanks in advance.
- (void)viewDidLoad
{
weeklyAudio=[UIButton buttonWithType:UIButtonTypeCustom];
[weeklyAudio addTarget:self action:#selector(weeklyPredictions) forControlEvents:UIControlEventTouchUpInside];
[weeklyAudio setTitle:#"WEEKLY PREDICTIONS" forState:UIControlStateNormal];
weeklyAudio.titleLabel.textAlignment = NSLineBreakByWordWrapping;
weeklyAudio.titleLabel.numberOfLines = 2;
[weeklyAudio.titleLabel setTextAlignment: NSTextAlignmentCenter];
[weeklyAudio setTitleEdgeInsets:UIEdgeInsetsMake(60, 10, 10, 10)];
[weeklyAudio.titleLabel setFont:[UIFont systemFontOfSize:14.0]];
weeklyAudio.frame=CGRectMake(10, 20, 140, 120);
weeklyAudio.layer.cornerRadius=5;
weeklyAudio.backgroundColor=[UIColor colorWithRed:232.0f/255.0f green:52.0f/255.0f blue:27.0f/255.0f alpha:1.0];
[backGroundImage addSubview:weeklyAudio];
weeklyAudioImage=[[UIImageView alloc]initWithFrame:CGRectMake(45, 10, 48, 48)];
weeklyAudioImage.image=[UIImage imageNamed:#"m48*48.png"];
[weeklyAudio addSubview:weeklyAudioImage];
weeklyAudio.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
}
-(void)weeklyPredictions
{
WeeklyViewController *weekly=[[WeeklyViewController alloc]init];
[self.navigationController pushViewController:weekly animated:NO];
}
set a breakpoint in -(void)weeklyPredictions, then debug to see if run in the method when you click the button. If run in it, print po [self navigationController] in console to see if the viewController has a navigation controller . If result is nil, then you can't push another view controller.
Add the following code before addSubview
[weeklyAudio addTarget:self action:#selector(weeklyPredictions) forControlEvents:UIControlEventTouchUpInside];
And edit your weeklyPredictions method as:
-(void)weeklyPredictions {
WeeklyViewController *weekly=[[WeeklyViewController alloc]initWithNibName:NSStringFromClass([WeeklyViewController class]) bundle:nil];
[self.navigationController pushViewController:weekly animated:NO];
}
Are you using a navigation controller to push and pop viewcontrollers? If not..
use
[self presentViewController:weekly animated:YES completion:nil];
to present your next viewcontroller.
You need to add the following line in your viewDidLoad menthol:
backGroundImage.userInteractionEnabled = YES;
Since by default user interaction is disabled for UIImageView so any subview added to image view will not get touch events.
Hope it will solve your problem, if yes please vote it.
Regards,
Satendra
Related
I am creating an iOS library. My library when initiated from AppDelegate will create a button on top of the screen.
I have created the button and it is showing up. But when I click, the target method is not evoked.
This is how I have created the button and assigned its action in the library
- (void) addLoginButton {
UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeSystem];
[loginButton setFrame:CGRectMake((appWindow.frame.size.width/2)-35, 20, 70, 20)];
[loginButton setBackgroundColor:[UIColor blueColor]];
[loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[loginButton setTitle:#"Login" forState:UIControlStateNormal];
[loginButton addTarget:self action:#selector(auLoginClicked) forControlEvents:UIControlEventTouchUpInside];
[appWindow addSubview:loginButton];
if([appWindow.rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navCon = (UINavigationController *)(appWindow.rootViewController);
if (!navCon.navigationBar.isHidden) {
navCon.navigationBar.layer.zPosition = 0;
}
}
loginButton.layer.zPosition = 5;
}
- (void) auLoginClicked {
NSLog(#"Hello");
}
I copied your code and have the same result.It's really strange and i am still working on it.I confirm it is the storyboard that caused the result,because i use your code in my project which does not use the storyboard,it works properly.
But please do not use loginButton.layer.zPosition = 5;It is not a proper way .
Here are some advices:
But If are you using UINavigationController Use:
[self.navigationController.view.window addSubview:aView];
If are you using UITabBarController Use:
[self.tabBarController.view.window addSubview:aView];
In AppDelegate you can directly assign a view to window. In appDelegate didFinishLaunchingWithOptions method Use:
[self.window addSubview:aView];
Hope it helps...
Instead of adding your button as a subview of window add this
then your button will get action.
[appWindow.rootViewController.view addSubview:loginButton];
If you add your view(Button) as a subview of window, then it won't be able to get events from user.That is the reason why your button not responding to event.
Debug it you will come to understand:)
If you want that to be on the top of every viewController, then check if UINavigationController is not the initialViewController then create a your own NavigationController and make it as initialContoller. It will make your button will be visible throughout the app(until the user by himself present any other VC)
UIWindow *appWindow = [UIApplication sharedApplication].keyWindow;
[appWindow addSubview:view];
You just need to fetch the keyWindow of the application and add the button as a subview. You don't have to set the zPosition
Can someone please explain to me the uibutton target functionality from this example:
I have a ViewController. I add a uiview with two buttons to this viewcontroller. One button is crated in the init and the other one is created by a method 'addSecondButton'. Both buttons have the same action on [self superview] target which is the ViewController. The code:
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
MySpecialView *myspecialview = [[MySpecialView alloc] initWithFrame:self.view.frame];
[self.view addSubview:myspecialview];
[myspecialview addSecondButton];
}
- (void)specialMethod { NSLog(#"right here!"); }
MySpecialView.m
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 30, frame.size.width, 50)];
[button addTarget:[self superview] action:#selector(specialMethod) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor blueColor];
[self addSubview:button];
}
return self;
}
- (void)addSecondButton {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 90, self.frame.size.width, 50)];
[button addTarget:[self superview] action:#selector(specialMethod) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor redColor];
[self addSubview:button];
}
So when tapping the blue button which is created in the init, specialMethod does execute. When pressing the red one which is added after the init, the app crashes with the warning - unknow selector for uiview.
What I really don't understand is when I NSLog [self superview] in the init, it is null, because the object is not yet created and returned to the superview, but the action does get executed for some reason.
Thanks for the help!
You have indeed added a nil target for the blue button in initWithFrameMethod. According to the Apple's Event Handling Guide, when you add a nil target, the message (specialMethod in your case) will be passed through the responder chain:
When the user manipulates a control, such as a button or switch, and the target for the action method is nil, the message is sent through a chain of responders starting with the control view.
As your ViewController is a part of the responder chain, it will receive this message and call its specialMethod.
[self superview] is a pointer to ViewController's view, not ViewController itself. The selector you are defining as the action for the button should target the instance of ViewController, not the ViewController's view since you have the method specialMethod defined in ViewController. If you really wanted to use [self superview] as the target for the action, then you'll need to subclass UIView, implement specialMethod and set that new UIView subclass as the view of the view controller (not a subview). This way, [self superview] will refer to a class that actually has the selector specified on the target.
I didn't actually try your code sample, but it's so obviously wrong, if it does work, it's coincidence and shouldn't be relied upon.
I just installed xcode 6 to test out how my app works with it.
The facebook login button on the initial page does not appear to be working.
Here is my code:
#property (nonatomic, strong) UIButton *loginButton;
- (void)viewDidLoad
{
[super viewDidLoad];
self.loginButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 70)];
self.loginButton.center = self.view.center;
[self.loginButton setImage:[UIImage imageNamed:#"login_fb.png"] forState:UIControlStateNormal];
[self.view addSubview:self.loginButton];
[self.loginButton addTarget:self action:#selector(loginButtonPressed) forControlEvents:UIControlEventTouchUpInside];
}
-(void)loginButtonPressed
{
// perform login
}
It is important to note that the app starts off on a different view. In that view controller I check to see if a user exists or not, and if not I present the login view. Here is that code:
if ([DCTUserIdentity currentIdentity] == nil) {
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
DCTInitialLoginVC *vc = [sb instantiateViewControllerWithIdentifier:#"InitialLogin"];
vc.delegate = self;
[self presentViewController:vc animated:NO completion:^{}];
}
I put a breakpoint in the loginButtonPressed function and it never gets hit when I try clicking on the button....any idea whats going on?
It appears that this is not actually a bug, but an incompatibility issue of targeting iOS 7 devices using Xcode 6. ecotax's post describes this in more detail, but here is the response from Apple DTS:
In iOS 7, cells’ content views sized themselves via autoresizing masks. In iOS 8, this was changed, cells stopped using the autoresizing masks and started sizing the content view in layoutSubviews. If a nib is encoded in iOS 8 and then decode it on iOS 7, you’ll have a content view without an autoresizing mask and no other means by which to size itself. So if you ever change the frame of the cell, the content view won’t follow.
Apps being deploying back to iOS 7 will have to work around this by sizing the content view itself, adding autoresizing masks, or adding constraints.
Workaround:
- (void)awakeFromNib
{
// Fix for iOS 7 devices targeted using Xcode 6.
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
Try this code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.loginButton.frame = CGRectMake(0, 0, 200, 70);
self.loginButton.center = self.view.center;
[self.loginButton setImage:[UIImage imageNamed:#"login_fb.png"]
forState:UIControlStateNormal];
[self.view addSubview:self.loginButton];
[self.loginButton addTarget:self action:#selector(loginButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
}
And hold your DCTInitialLoginVC object with strong pointer.
I have a ViewController with a NavigationController and I want to add a translucent UIView with some Buttons over the ViewController when I press a ViewController button, the problem is that I can not put the UIView over the NavigationBar. How can I solve this?
This is my code ( Very simple)
-(void)setOpacityView
{
opacityVw = [[UIView alloc] initWithFrame:self.view.bounds];
opacityVw.backgroundColor = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
WPCustomButton *closeBtn = [[WPCustomButton alloc] initWithFrame:CGRectMake(230, 10, 80, 20)];
[closeBtn setTitle:#"Close X" forState:UIControlStateNormal];
[closeBtn setBackgroundColor:[UIColor clearColor]];
[closeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[closeBtn addTarget:self action:#selector(closeView) forControlEvents:UIControlEventTouchUpInside];
[opacityVw addSubview:closeBtn];
}
// ---------------------------------------------------------------------------------------------------------------------
#pragma mark - Button methods
-(void) closeView
{
[opacityVw removeFromSuperview];
}
-(void)setProfileImage
{
[self setOpacityView];
[self.view addSubview:opacityVw];
}
I answered a similar question here
Try something like this:
-(void)setProfileImage
{
[self setOpacityView];
[self.navigationController.view addSubview:opacityVw];
}
Add it to the AppDelegate's UIWindow instead.
- (void)setProfileImage
{
[self setOpacityView];
[ [[UIApplication sharedApplication] delegate].window addSubview:opacityVw];
}
Don't forget to change your view size:
opacityVw = [[UIView alloc] initWithFrame:[[[UIApplication sharedApplication] delegate]window].bounds];
You can create MainViewController and put that as your window.rootViewController. Add your navigationController to this MainViewController. After that it you add the view to your mainViewController, it would be on top of navigation Controller.
Just make it simple :
-(void)setProfileImage
{
[self setOpacityView];
self.navigationController.navigationBarHidden = YES;
[self.view insertSubview:opacityVw aboveSubview:self.view];
}
-(void) closeView
{
[opacityVw removeFromSuperview];
self.navigationController.navigationBarHidden = NO;
}
I have one tableview in my viewcontroller and in that i have customTableViewCell.i have dynamic buttons which generated runtime in my customeview cell.and on that button's click i want to push my view controller which is holding my tableview controller with the customtableviewcell to another view controller so how can i do it ?
in my custometableviewcell.m file i have this button.
CommentButton = [[UIButton alloc]init];
CommentButton.frame = CGRectMake(CommentLabel.frame.origin.x+CommentLabel.frame.size.width+5, 5, 110, 35);
CommentButton.titleLabel.font = [UIFont systemFontOfSize:12];
[CommentButton setTitle:#"Add Comment" forState:UIControlStateNormal];
CommentButton.backgroundColor = [UIColor clearColor];
[CommentButton addTarget:self action:#selector(GoToComment:) forControlEvents:UIControlEventTouchUpInside];
folowing is my postnotification in customtableviewcell.m file which will called on comment button click
-(IBAction)GoToComment:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:#"GoToComment" object:nil];
}
above is my button on this i have registered on NSNotification which is called the following method
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(GotoComents)
name:#"GoToComment" object:nil];
above line is in viewdidload of my viewcontroll in which i have tableview with that customtableviewcell.
and from customtableview cell i am posting the above notofication wich will push the new view controller
-(void)GotoComents
{
TableTextViewController *settingView=[[TableTextViewController alloc]initWithNibName:#"TableTextViewController" bundle:nil];
[self.navigationController pushViewController:settingView animated:YES];
}
right now i have just did it with the nsnotofication center which just call from my customTableViewcell and invoke the viewcontroller method.
but is it right way to do it?if its not then can anyone please help me how can i achieve this.?
remember that i have dynamic button which generated runtime.so please can any one guide me?
on click button event
-(void)buttonAction:(UIButton*)sender
{
YourViewControllerVC *yvc=[YourViewControllerVC alloc] init];
[self.yournavigatioonController pushViewController:yvc animated:YES];
}
You can declare your TableViewController subclass as custom cell delegate, create GoToComment method inside it, then, instead of
[CommentButton addTarget:self action:#selector(GoToComment:) forControlEvents:UIControlEventTouchUpInside];
do
[CommentButton addTarget:self.delegate action:#selector(GoToComment:) forControlEvents:UIControlEventTouchUpInside];
Add target-action for dynamically generated button:
[myButton addTarget:targetObject action:#selector(actionMethod) forControlEvents:UIControlEventTouchUpInside];
Then implement actionMethod for the targetObject and it will be called whenever button is touched. In this action method you need the following code:
UIViewController *viewController = [[UIViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
you have not described your question correctly ..
you can do what you want this way:
LoginViewController * login_view = [[ LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
UINavigationController *Nav01 = [[UINavigationController alloc] initWithRootViewController:login_view];
Nav01.navigationBar.hidden = YES;
login_view.fromProfileView = FALSE;
[self presentModalViewController:Nav01 animated:YES];
I think what you need is
- (UIViewController *)viewController {
for (UIView* next = [self superview]; next; next = next.superview) {
UIResponder *nextResponder = [next nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]]) {
return (UIViewController *)nextResponder;
}
}
return nil;
}
With above code, you can find your current view controller inside your custom cell.
You got to add your button in this way :
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[view addSubview:button];
where aMethod is an IBAction returning method.