UIButton click not working if subview of UIWIndow - ios

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

Related

Uinavigation Controller issues

Hi i created UInavigation controller in iOS programatically but the problem is when i move to next view controller i am directing to same screen.I created another view with name InfoView but when i push to InfoView it shows the same screen with buttons that i created in ViewController.
#import "AppDelegate.h"
#import "ViewController.h"
#interface AppDelegate ()
{
UINavigationController *navigation;
}
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
navigation = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
#import "ViewController.h"
#import "InfoView.h"
#interface ViewController ()
{
UIButton *RealVideo,*listen,*Readmat,*Look,*DiveIn;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor=[UIColor whiteColor];
[self designDeclare];
}
-(void)designDeclare{
RealVideo=[UIButton buttonWithType:UIButtonTypeCustom];
RealVideo.frame=CGRectMake(10,self.view.frame.size.height*0.2, CGRectGetWidth(self.view.frame)-20, CGRectGetHeight(self.view.frame)/7);
[RealVideo addTarget:self action:#selector(real:) forControlEvents:UIControlEventTouchUpInside];
[RealVideo setTitle:#"Real Video" forState:UIControlStateNormal];
RealVideo.backgroundColor=[UIColor colorWithRed:0.744f green:0.000f blue:0.000f alpha:1.00f];
[self.view addSubview:RealVideo];
listen=[UIButton buttonWithType:UIButtonTypeCustom];
listen.frame=CGRectMake(CGRectGetMinX(RealVideo.frame),CGRectGetMaxY(RealVideo.frame)+20, CGRectGetWidth(RealVideo.frame), CGRectGetHeight(RealVideo.frame));
// [listen addTarget:self action:#selector(Listen:) forControlEvents:UIControlEventTouchUpInside];
[listen setTitle:#"Listen" forState:UIControlStateNormal];
listen.backgroundColor=[UIColor purpleColor];
[self.view addSubview:listen];
Readmat=[UIButton buttonWithType:UIButtonTypeCustom];
Readmat.frame=CGRectMake(CGRectGetMinX(RealVideo.frame),CGRectGetMaxY(listen.frame)+20, CGRectGetWidth(RealVideo.frame), CGRectGetHeight(RealVideo.frame));
// [Readmat addTarget:self action:#selector(Listen:) forControlEvents:UIControlEventTouchUpInside];
[Readmat setTitle:#"Reading Material" forState:UIControlStateNormal];
Readmat.backgroundColor=[UIColor colorWithRed:0.000f green:0.412f blue:0.851f alpha:1.00f];
[self.view addSubview:Readmat];
Look=[UIButton buttonWithType:UIButtonTypeCustom];
Look.frame=CGRectMake(CGRectGetMinX(RealVideo.frame),CGRectGetMaxY(Readmat.frame)+20, CGRectGetWidth(RealVideo.frame), CGRectGetHeight(RealVideo.frame));
[Look addTarget:self action:#selector(Look) forControlEvents:UIControlEventTouchUpInside];
[Look setTitle:#"Look" forState:UIControlStateNormal];
Look.backgroundColor=[UIColor colorWithRed:0.400f green:1.000f blue:0.400f alpha:1.00f];
[self.view addSubview:Look];
DiveIn=[UIButton buttonWithType:UIButtonTypeCustom];
DiveIn.frame=CGRectMake(self.view.frame.size.width*0.7,CGRectGetMaxY(Look.frame)+20, CGRectGetWidth(RealVideo.frame)/4,CGRectGetHeight(RealVideo.frame)/1.5);
[DiveIn setTitle:#"Dive In" forState:UIControlStateNormal];
DiveIn.backgroundColor=[UIColor colorWithRed:0.941f green:0.471f blue:0.353f alpha:1.00f];
[self.view addSubview:DiveIn];
}
-(void)real:(id)sender{
}
-(void)Look{
InfoView *infoVC=[[InfoView alloc]init];
[self.navigationController pushViewController:infoVC animated:YES];
}
]1
A navigation controller works like a stack so you can push and pop viewcontroller exactly like a stack behaves in the real world. Think of a navigation controller as a stack of viewcontrollers, so you cant actually add a UIView, but what you would like to do instead is to add the uiview as a subview in your view controller and push that view controller onto the navigation controller stack with a simple:
[navigationcontroller pushViewController:aViewcontroller];
Please read through Apple Documentation for more insight.
You can't push a View. You need to push a View Controller.
If you want to show the View on top of the same View Controller, then you need to add the InfoView as the subView, preferably with animation.
But if you wanted to push the InfoView then you should create a UIViewController in your Storyboard and then add the InfoView as that View Controller's subview.
Let's say you create a new View Controller called InfoViewcontroller which is going to hold the InfoView. Now go to the InfoViewcontroller's -viewDidLoad method and add the following line
InfoView *infoVC=[[InfoView alloc]initWithFrame:self.view.frame];
[self.view addSubview:infoVC];
However, as you don't want to touch your storyboard, you may want to add it as a subView with animation. So, you can change your Look method with something like-
-(void)Look{
InfoView *infoVC=[[InfoView alloc]initWithFrame:self.view.frame];
[UIView transitionWithView:self.view
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.view addSubview:infoVC];
}
completion:NULL];
}
When the InfoView.m looks like-
#import "InfoView.h"
#implementation InfoView
-(id)initWithFrame:(CGRect)frame{
self=[super initWithFrame:frame];
if(self){
self.backgroundColor=[UIColor whiteColor];
}
return self;
}
#end
Note: you need an -initWithFrame method as your InfoView needs to know it's frame size.

Custom button in AVPlayerViewController.ContentOverlayView

I need to add a custom button to the AVPlayerViewController that will appear in both fullscreen and non-fullscreen for an app running iOS 8.
Adding a button to the AVPlayerViewController.view or the containing view will work for non-fullscreen but when the player switches to fullscreen the button is no longer visible. I have found that if I add a button to the AVPlayerViewController.ContentOverlayView then it appears in fullscreen and non-fullscreen, but then it doesn't appear that the ContentOverlayView responds to any touches so the button cannot be clicked. Does anyone know of a different place to add the button or a way to make the ContentOverlayView respond to touches?
Example Code
AVPlayerViewController *playerView = [[AVPlayerViewController alloc] init];
playerView.player = [AVPlayer playerWithURL:movieURL];
CGRect viewInsetRect = CGRectInset ([self.view bounds],
kMovieViewOffsetX,
kMovieViewOffsetY );
/* Inset the movie frame in the parent view frame. */
[[playerView view] setFrame:viewInsetRect];
[self.view addSubview: [playerView view]];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor yellowColor];
btn.frame = CGRectMake(50, 50, 200, 75);
[btn addTarget:self action:#selector(didSelectButton:) forControlEvents:UIControlEventTouchUpInside];
[btn setUserInteractionEnabled:YES];
[btn setEnabled:YES];
[playerView.contentOverlayView addSubview:btn];
I managed to get this working by adding the following to my AVPlayerViewController in IB:
An overlay view with a button inside it
Add constraints to center the button in the overlay view
Created an IBOutlet to the view (I called it 'overlay')
Created an action from the button to AVPlayerViewController that prints something so that we can see that tapping the button is working
Dragged the overlay view out of the view hierarchy and onto the top bar of the view controller (appears as a view icon in top bar of the view controller along with the exit icon etc)
and then in the code for the AVPlayerViewController:
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.overlay)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.overlay.frame = self.view.bounds
}
#IBAction func playBtnTapped(sender: AnyObject) {
println("PlayBtnTapped")
}
The button is now centered in fullscreen/normal viewing and the button works
I had the same predicament just now.
Instead of:
[playerView.contentOverlayView addSubview:btn];
use (after you add the playerView)
[self.view addSubview:btn];
This will add the button in the minimised player.
Now for the fullscreen I didn't found any other reliable method of checking if the player went fullscreen or back, so here is a a solution:
self.windowChecker = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(checkIfFullscreen) userInfo:nil repeats:YES];
and this:
-(void)checkIfFullscreen{
NSLog(#"videoBounds\n %f %f ", self.avVideoPlayer.contentOverlayView.frame.size.width,self.avVideoPlayer.contentOverlayView.frame.size.height);
if ([self playerIsFullscreen]) { // check the frame on this
for(UIWindow* tempWindow in [[UIApplication sharedApplication]windows]){
for(UIView* tempView in [tempWindow subviews]){
if ([[tempView description] rangeOfString:#"UIInputSetContainerView"].location != NSNotFound){
UIButton *testB = [[UIButton alloc] initWithFrame: CGRectMake(20, 20, 400, 400)];
testB.backgroundColor = [UIColor redColor];
[testB addTarget:self action:#selector(buttonTouch) forControlEvents:UIControlEventTouchDown];
[tempView addSubview:testB];
break;
}
}
}
}
}
I know this is a not a nice way to do it, but it is the only way I managed to add some custom UI that also receives touch events on the player.
Cheers!

how can I remove a facebook login view controller?

I am trying to remove a facebook view controller that I created. Basically, the showFBLoginView method that initializes the view controller is the App Delegate and called within a GameOver layer.
-(void)showFBLoginView {
facebookViewController = [[FacebookViewController alloc] init];
self.facebookViewController = facebookViewController;
// Set loginUIViewController as root view controller
[[self window] setRootViewController:facebookViewController];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[self.facebookViewController activateButton:#"Facebook Connect"];
.
.
.
}
The activateButton method within the facebookViewController.m class:
-(void)activateButton:(NSString*)buttonText {
CGSize screenSize = [[CCDirector sharedDirector] winSize];
fbConnectButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
fbConnectButton.frame = CGRectMake(screenSize.width/2 - 50*(screenSize.width/480) , screenSize.height/2, screenSize.width/4, screenSize.height/12);
[fbConnectButton setTitle:buttonText forState:UIControlStateNormal];
fbConnectButton.backgroundColor = [UIColor redColor];
[fbConnectButton setTitleColor:[UIColor brownColor] forState:UIControlStateNormal ];
[fbConnectButton addTarget:self action:#selector(callButtonTouched) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:fbConnectButton];
}
I tried to remove the faceboookViewController in the following way. This was done within the App Delegate.
[[self window] removeFromSuperview];
But it's not working. What is the right way to remove the view controller?
faceboookViewController *fbViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"StoryboardID"];
[self dismissViewControllerAnimated:YES completion:nil];
StoryboardID is StoryboardID of faceboookViewController.
you can dismiss if you present it.

How to Navigate UIViewController as target of UIButton action created in programmatically

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

How to push New View Controller From any dynamic button click which is in CustomTableViewCell?

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.

Resources