Team,
I am trying to bring a menu in top of all visible views during runtime. This menu should be easily addable and removable dynamically in certain conditions.
To do this, I have tried adding a button view to the UIWindow as a subview during runtime.
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:nil forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[window addSubview:button];
[window makeKeyAndVisible];
[window bringSubviewToFront:button];
But it doesnt worked. Also I have tried to place this button in the root view controller, but no luck again.
Edit - Note: This code is not from a UIViewController. I am trying to build a library this will be in that library code. Use case be like you could post NSNotification to enable and disable this menu dynamically during runtime.
Please suggest.
Thanks !
An easier way would be add the menu view to the controller's view. You will have some benefits:
It will handle rotation correctly
You do not mess with window
Taking a look to your code, I should suppose that you are using it inside a view controller, thus you do not need to call [window makeKeyAndVisible]. Also, you are not showing which window you are talking about. Are you creating it? are you using the one of your root view controller?
in appdelgate.h
-(void)addMarketOpenCloseIcon;
in appdelgate.m
#pragma mark Add Market Open Close Label
-(void)addMarketOpenCloseIcon
if (lblMarketOpenClose==nil) {
lblMarketOpenClose=[[UILabel alloc ] initWithFrame:CGRectMake(116,20, 80, 21)];
lblMarketOpenClose.textColor=[UIColor redColor];
[lblMarketOpenClose setBackgroundColor:[UIColor clearColor]];
lblMarketOpenClose.font=[UIFont fontWithName:#"Arial" size:12];
[self.window addSubview:lblMarketOpenClose];
}
}
#pragma mark DidFinishLauch
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//create all table
LoginViewController *login=[[LoginViewController alloc]initWithNibName:#"LoginViewController" bundle:nil];
navigationController = [[ UINavigationController alloc] initWithRootViewController:login];
[self.window setRootViewController:navigationController];
self.navigationController.navigationBarHidden=YES;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
In LoginViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
appdelgate=[[UIApplication sharedApplication]delegate];
[appdelgate addMarketOpenCloseIcon];
}
You want to display something that floats over all of the user's views. You want to implement this in a library to be used generically.
That sounds a lot like a UIAlertView. Why not implement it the same way as UIAlertView? Create a new UIWindow and set its windowLevel to UIWindowLevelAlert. Put your “floating” content in your own UIWindow.
You can find some useful tips for creating a second UIWindow in this Q&A.
Create UIWindow object, add the button on it and then add the UIWindow object into [UIApplication sharedApplication].keyWindow
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIWindow *buttonWindow = [UIWindow alloc] initWithFrame: self.view.bounds]
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:nil forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[buttonWindow addSubview: button];
[keyWindow addSubview: buttonWindow]
[buttonWindow makeKeyAndVisible]
[backgroundWindow bringSubviewToFront:button];
Related
Okay, so this is pretty weird; before upgrading to the final GMseed of Xcode my buttons worked perfectly fine...
Now I can't even do them on a super simple scale without the program crashing on click.
The absolute most bizarre aspect is that it works SOME of the time, but like 85%, it just crashes; and when it does work, it'll crash after extensive use.
Here is my code (stripped down to the simplest button implementation I could think of):
#interface TESTViewController ()
{
UIButton *button;
}
#end
#implementation TESTViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self addButton];
[button addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchDown];
}
- (void)addButton
{
button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 45)];
[button setTitle:#"CLICK" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:button];
}
- (void)buttonPressed
{
NSLog(#"WORKED");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
TESTViewController *test = [[TESTViewController alloc] init];
[self.window addSubview:test.view];
return YES;
}
I've tried creating the button in the init function, viewDidLoad -- neither works consistently, though viewDidLoad seems to work a little more frequently...
I tried -(void) addButton:(UIButton*)button as well
Using:
[button addTarget:self action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchDown];
--No difference.
I am at a total loss. I tried looking it up here on the forums, but unfortunately most of it refers to programming with IBActions.
The error I get is bad access
So my guess is that when the button is clicked, it's not actually accessing the buttonPressed function but something else entirely... I have no clue as to why this would be the case...
Thanks for any help!
The problem is in your "didFinishLaunchingWithOptions" method. Here you are creating a local object which gets Deallocated i.e "TESTViewController *test = [[TESTViewController alloc] init]".
You should retain this object, so try making it a property and use "self.test = [[TESTViewController alloc] init]". It will work.
Also conventionally you should use rootViewController rather adding your viewController to windows's subview.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.test = [[TESTViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = self.test;
[self.window makeKeyAndVisible];
return YES;
}
I think you have a memory leak on that Button object are you using ARC or manual memory management? If manual make sure you retain it. If it is ARC use a property and the compiler will do the rest of the work
#property (nonatomic, strong) UIButton *button;
try it this way
- (void)addButton
{
button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 45)];
[button addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"CLICK" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:button];
}
and remove
[button addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchDown];
this line from viewDidLoad
I am not sure if this is the cause of the crash but actions (like your buttonPressed) should have a sender parameter:
[button addTarget:self action:#selector(buttonPressed:)
- (void)buttonPressed:(id)sender
{
...
}
To define a button programatically use the buttonWithType method, Try this
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(buttonPressed)
forControlEvents: UIControlEventTouchUpInside];//Any control event type
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, 80, 45);
[view addSubview:button];
I want to show a subview that will contain list of menu when a UIbutton is pressed. Should I use vertical SegmentControl?
Thanks for any help in advance
You don't have to use vertical TabbarViewController.
First of all, go to the interface builder and drag a Button, connect the Button to an action method you declare in the .m file
let's said that the method is
- (IBAction) btnHandler :(id)sender {
}
then declare a new view and add it to your main view
so the btnhandler method will look like this
- (IBAction) btnHandler :(id)sender {
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 320, 300)];
//here add what ever you want to the new created view using the
//[subview addSubview:(your Componant)];
[self.view addSubview:subview];
}
please forgive me if i made a mistake, this is not tested code. i write it now in the browser.
If its an iPad application, maybe consider calling a UIPopOverController
You could use an Action Sheet if you're aiming for a native iOS look and feel.
Agree with the previous answer that a pop over is a great option if this is an iPad app.
You could go full custom of course with your own viewController which you can animate in from the top or bottom depending on your need.
Option 1:
Design the view in your nib.
Option 2:
Have a separate view controller
You can use addSubView method to add the view when you press the UIButton
Try below code that will help you.
- (void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
[super viewDidLoad];
}
-(IBAction)buttonPressed:(id)sender
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10, 200, 300, 100)];
view.backgroundColor = [UIColor clearColor];
view.backgroundColor = [UIColor grayColor];
[self.view addSubview:view];
}
I'm trying to use dynamic buttons created via code (no IB) in my project and they appear where and how I want them but they don't fire their actions.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(475, 302, 49, 58);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
[myImageView addSubview:button1];
-(void)goToFirstTrailer {
[self startAnimator:#"OutsideToTrailer1_" forNumFrames:60];
}
The imageView this is placed on has buttons and User Interaction Enabled On.
Any light you can shed would be much appreciated.
I think you have the wrong signature of the action method change that line to
-(void) goToFirstTrailer:(id)sender {
and where you set the action to
[button1 addTarget:self action:#selector(goToFirstTrailer:) forControlEvents:....
Important is the colon after the message name because I changed the action method signature to include the sender.
Edit I wrote a small sample project with just an imageView in the MainWindow.xib and created a button programmatically as follows
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(0.f, 0.f, 50.f, 50.f);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer:)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
imageView.userInteractionEnabled = YES; // <--- this has to be set to YES
[imageView addSubview:button1];
[self.window makeKeyAndVisible];
return YES;
}
It is quick and dirty and yes, I am misusing the application delegate as the view controller. I know it is bad.
Here is the action method
- (void) goToFirstTrailer:(id)sender {
imageView.backgroundColor = [UIColor redColor];
}
Setting the userInteractionEnabled property on the parent imageView makes the difference. With it set to NO which is the default, no events are routed to the button.
If myImageView is a UIImageView object, adding a subview to it (like UIButton) only displays the image that object is represented by. If you add that UIButton as a subview of a UIView, it should work perfectly. Try adding an auxiliary UIView to your UIImageView and then add your button to a subview of the new auxiliary UIView, that should solve your problem.
This works fine for me. Note that I changed the event to UIControlEventTouchUpInside to allow the button press down state to be visible first.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(20,400,88,35); //The position and size of the button (x,y,width,height)
[btn setTitle:#"Quit" forState:UIControlStateNormal];
[btn addTarget:self
action:#selector(showAbout)
forControlEvents:(UIControlEvents)UIControlEventTouchUpInside];
[self.view addSubview:btn];
I've been trying to get a basic app working that doesnt use an XIB. It simply should load and draw a button.
At the moment the screen just appears white with apparently nothing on it.
In my delegate I pass across to my viewController Class.
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
return YES;
}
In my viewController class I implement loadview and viewDidLoad. Not sure if loadView is getting called. There is no XIB in this project.
-(void)viewDidload
{
[super viewDidLoad];
UIButton *singlePlayerButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect]
retain];
singlePlayerButton.frame = CGRectMake(50.0, 30.0, 100.0, 30.0);
[singlePlayerButton setTitle:#"Test" forState:UIControlStateNormal];
singlePlayerButton.backgroundColor = [UIColor blueColor];
[singlePlayerButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal ];
[singlePlayerButton addTarget:self action:#selector(playAction:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:singlePlayerButton];
}
-(void)loadView
{
NSLog(#"loadView");
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen]
applicationFrame]];
self.view = view;
[view release];
}
Is there something I am missing?
I though this would be really quiet simple but after 2hrs of hitting my head against the wall nothing has changed.
Thanks -Code
Your viewDidload method has a case typo. It should be viewDidLoad (capital L).
Stupid suggestion perhaps, but where in the app delegate are you instantiating viewController?
been looking at this for days..
- (void)viewDidAppear:(BOOL)animated {
#if !TARGET_IPHONE_SIMULATOR
UIButton *returnButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
returnButton.frame = CGRectMake(0, 0, 100, 100);
[returnButton setTitle:#"Tap here to return" forState:UIControlStateNormal];
[returnButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:returnButton];
[self.view bringSubviewToFront:returnButton];
[[self cameraController] setCameraOverlayView:[self view]];
[self presentModalViewController:[self cameraController] animated:YES];
[[self view] setFrame:[[[self cameraController] view] bounds]];
#endif
[super viewDidAppear:animated];
}
I think you need to hide the defaul camera control first by using : [[self cameraController] setShowsCameraControls:NO] . See more here
The default value of this property is YES, which specifies that the default camera controls are visible in the picker. Set it to NO to hide the default controls if you want to instead provide a custom overlay view using the cameraOverlayView property.
[[self cameraController] setCameraOverlayView:[self view]]; is almost certainly wrong. When viewDidAppear: is called, your view is already in the view hierarchy. Suddenly setting it as the cameraOverlayView is unlikely to do the right thing.