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.
Related
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];
I have added multiple actions to one button
Play audiofile
Display array of views
Button is playing audiofile but not displaying views.
UIButton *playpauseButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playpauseButton addTarget:self action:#selector(playpauseAction:) forControlEvents:UIControlEventTouchUpInside];
[playpauseButton addTarget:self action:#selector(displayviewsAction:) forControlEvents:UIControlEventTouchUpInside];
playpauseButton.frame = CGRectMake(0, 0, 50, 50);
[playpauseButton setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[playpauseButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
UIBarButtonItem *playpause = [[UIBarButtonItem alloc] initWithCustomView:playpauseButton];
Play Pause Action coding
-(void)playpauseAction:(id)sender
{
if
([audioPlayer isPlaying]){
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
} else {
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
}
}
DisplayviewsAction coding
- (void)displayviewsAction:(id)sender
{
CGRect pageViewRect = self.view.bounds;
pageViewRect = CGRectInset(pageViewRect, 30.0, 30.0);
self.pageViewController.view.frame = pageViewRect;
// Configure the page view controller
UIPageViewController *pageViewController = [[[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]autorelease];
NSArray *viewControllers = [NSArray arrayWithObject:pageViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self.view addSubview:self.pageViewController.view];
}
Any advice what i m missing in the code or doing wrong.
Thanks for help.
Here are some minor corrections you should make - they may not all help with the problem, but you never know.
Add a completion block here:
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
I don't remember for sure, but I think setViewControllers is done asynchronously - nothing cannot be added until after the completion handler is done. To add the block, you simply put a ^ and a block of code in (like a normal method):
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:^{
// your code here.
}];
This may fix the problem, but I cannot be sure until I can get back to my computer.
You should also put an NSLog at the beginning of every method, at least until you are done debugging. That way, you always know what is being called and what isn't. If it is not called, try removing the autorelease from the pageViewController - it may be released because it isn't being used.
I think the issue is in displayviewsAction, try something more simple like:
- (void) displayviewsAction:(id)sender
{
UIView* testView = [[UIView alloc] initWithFrame:CGRectInset(self.view.bounds, 30.0, 30.0)];
testView.backgroundColor = [UIColor greenColor];
[self.view addSubview:testView];
[testView release];
}
That should help you narrow down the problem. Depending on what your final aim is you might not need all those view controllers; instead consider UIView's transitionFromView... for the animation effects.
In Cocos2d, I have read that
[[[[CCDirector sharedDirector] openGLView] window] addSubview:someButton];
will add a UIView to the main window: http://www.cocos2d-iphone.org/forum/topic/3588
Yet in my code I have this:
- (void)onEnterTransitionDidFinish {
UIButton* button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[[[[CCDirector sharedDirector] openGLView] window] addSubview:button];
}
But no button is visible. This method is part of a CCLayerColor which is the first scene presented in the app, if that matters. What am I doing wrong here? Thanks!
Edit: I can confirm that the buttons are being added to the windows subviews, because NSLogging
[[[[[CCDirector sharedDirector] openGLView] window] subviews] count]
shows a difference when I comment/uncomment the addSubview line. So why isn't the button showing up?
Edit 2:
Thanks to #Marine, I have found that my problem is the way I am declaring my button; using buttonWithType: solved the problem, because this code works:
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(100, 100, 100, 100)];
[[[[CCDirector sharedDirector] openGLView] window] addSubview:button];
Can someone explain to me why using this class method works and using initWithFrame: doesn't? Because I would rather not create lots of autoreleased objects, and also because I have some UIButton subclasses that do NOT show up when I use the buttonWithType: method.
Edit 3 (Solution):
The reason why using anything but buttonWithType: doesn't work is that if you do not use that method to create the button, the background color of the button is not set, and by default it is clearColor. Using [button setBackgroundColor:[UIColor redColor]] or any other color fixes the problem. Also, if using a custom button class like this one, you might need to manually call [button awakeFromNib] if the button isn't connected to a nib.
Try the below code it would help you
-(id) init
{
if((self = [super init]))
{
UIView* glView = (UIView*) [[CCDirector sharedDirector] openGLView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(100, 100, 250, 250)];
[btn addTarget:self action:#selector(actionper:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:btn];
}
return self;
}
-(void) actionper : (id) sender
{
printf("\n Stuff of the Code on button Press");
}
I have posted the solution to the problem as an edit to the question.
Try using the bringsubviewtofront method of the OpenGL window passing the recently added button as the argument. Also make sure that the frame of your button is such that it is in the visible part of the screen. Try playing around with it's position.
using this tutorial I set up a custom TabBar. Unfortunately the tutorial won't describe how to hide the custom TabBar in views you don't wanna display it.
In my customTabBar.h I defined
- (void) hideAlsoCustomTabBar;
- (void) showCustomTabBarAgain;
which are implemented as
- (void) hideAlsoCustomTabBar {
btn1.hidden = YES;
btn2.hidden = YES;
btn3.hidden = YES;
btn4.hidden = YES;
}
- (void) showCustomTabBarAgain {
btn1.hidden = NO;
btn2.hidden = NO;
btn3.hidden = NO;
btn4.hidden = NO;
}
Calling those inside CustomTabBar.m's viewDidAppear works fine and does exactly what I expect them to do. If I try to call those methods from the ViewController where I need to hide the TabBar like this
[customTabs hideAlsoCustomTabBar];
inside the initWithNibName OR viewDidLoad OR viewWillAppear, nothing will happen. I checked with NSLog, the method gets called, but when I read out the BOOL for any buttons .hidden attribute, it returns 0, when it should be 1 (for hidden==YES).
I don't know what's wrong with my setup. Is it possible these button's attributes are private by default as CustomTabBar inherits from UITabBarController and I can't set them? Or did I make a mistake in the call?
Thanks!
EDIT
The TabBar implementation as it is described in the tutorial
import "CustomTabBar.h"
#implementation CustomTabBar
#synthesize btn1,btn2,btn3,btn4;
- (void) viewDidAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self hideExistingTabBar];
[self addCustomElements];
}
- (void) hideExistingTabBar {
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UITabBar class]]) {
view.hidden = YES;
break;
}
}
}
- (void) addCustomElements {
//Initialise the two images for btnEinleitung, not selected and selected
UIImage *btnImage = [UIImage imageNamed:#"btnEinl.png"];
UIImage *btnImageSelected = [UIImage imageNamed:#"btnEinl_s.png"];
self.btnEinleitung = [UIButton buttonWithType:UIButtonTypeCustom];
btnEinleitung.frame = CGRectMake(0, 430, 86, 50);
[btnEinleitung setBackgroundImage:btnImage forState:UIControlStateNormal];
[btnEinleitung setBackgroundImage:btnImageSelected forState:UIControlStateSelected];
[btnEinleitung setTag:0];
[btnEinleitung setSelected:true];
//set other buttons
btnImage = [UIImage imageNamed:#"btnUbg.png"];
btnImageSelected = [UIImage imageNamed:#"btnUbg_s.png"];
self.btnUebungen = [UIButton buttonWithType:UIButtonTypeCustom];
btnUebungen.frame = CGRectMake(86, 430, 80, 50);
[btnUebungen setBackgroundImage:btnImage forState:UIControlStateNormal];
[btnUebungen setBackgroundImage:btnImageSelected forState:UIControlStateSelected];
[btnUebungen setTag:1];
/* do the same for btn3 and btn4*/
//add custom buttons to view
[self.view addSubview:btn1];
[self.view addSubview:btn2];
[self.view addSubview:btn3];
[self.view addSubview:btn4];
//setup event handlers so the buttonClicked method will respond to the touch up inside event
[btn1 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn2 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn3 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn4 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
//set tab to active according to the passed tag number
- (void) selectTab:(int)tabID {
switch (tabID) {
case 0:
[btnEinleitung setSelected:TRUE];
[btnUebungen setSelected:FALSE];
[btnTipps setSelected:FALSE];
[btnBrauchtum setSelected:FALSE];
btnEinleitung.userInteractionEnabled = NO;
btnUebungen.userInteractionEnabled = YES;
btnTipps.userInteractionEnabled = YES;
btnBrauchtum.userInteractionEnabled = YES;
break;
case 1:
[btnEinleitung setSelected:FALSE];
[btnUebungen setSelected:TRUE];
[btnTipps setSelected:FALSE];
[btnBrauchtum setSelected:FALSE];
btnEinleitung.userInteractionEnabled = YES;
btnUebungen.userInteractionEnabled = NO;
btnTipps.userInteractionEnabled = YES;
btnBrauchtum.userInteractionEnabled = YES;
break;
// and so on for 2 and 3
}
self.selectedIndex = tabID;
}
//get the tag of the sender/pressed button, call the function selectTab
- (void) buttonClicked:(id)sender {
int tagNum = [sender tag];
[self selectTab:tagNum];
}
EDIT
As described below, I have 4 Tabs in a Tabbar which was generated with IB, added Navigation Controller with their ViewControllers, made Outlets for those and connected them in IB.
Clicking on the second Tab (e.g. sndMenuVC) opens a view with 4 buttons. Clicking one of these buttons leads to another view (e.g. detailVC) in which I don't want the TabBar to be displayed. detailVC has it's own nib.
Opening detailVC happens with the button's action declared like this
- (IBAction) openFourth:(id)sender{
detailVC *detailView = [[detailVC alloc] initWithNibName:#"detailVC" bundle:nil andSender:kFourthButtonSender];
[self.navigationController pushViewController:detailView animated:YES];
[detailView release];
}
As this is a custom initWithNibName, this is how I implemented it
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andSender: (NSString *)calledByButton{
self.callingButton = calledByButton;
[super initWithNibName:#"detailVC" bundle:nil];
return self;
}
SO I basically just set a global variable "callingButton" according to the transmitted sender and call the "normal" initWithNibName afterwards.
This all works fine.
If I try to call hideAlsoCustomTabBar, and NSLog the value of btn1.hidden it returns 0 when called from detailVC, but returns 1 when called from within CustomTabBar and actually hides the buttons.
I have customTabs as IBOutlet if needed, but don't know if this is connected correctly to the TabBarController of type CustomTabBar.
Hope this helps to understand me :) If you need any other information, just let me know.
Thanks!
I have written a follow up to my RXCustomTabBar tutorial which should answer your questions. I don't see any point reproducing it in full here.
Hiding your New Custom UITabBar (RXCustomTabBar follow up)
Let me know if you have any questions,
Oli
if you want to hide the tabBar you can simply, in your view controller, call
[[[self tabBarController] tabBar] setHidden:YES];
In RXCustomTabBar.m file addCustomElements function is called from viewDidAppear.
-(void)addCustomElements
{
.
.
.
.
// Add my new buttons to the view
// Following lines are adding buttons to the view. Put your condition here according to requirement so that it will check and add buttons accordingly.
[self.view addSubview:btn1];
[self.view addSubview:btn2];
[self.view addSubview:btn3];
[self.view addSubview:btn4];
.
.
.
.
}
Hope this helps.
Update
//Add following function in RXCustomTabBar.m
-(void)hideButtons
{
btn1.hidden = YES;
btn2.hidden = YES;
btn3.hidden = YES;
btn4.hidden = YES;
}
- (void)selectTab:(int)tabID
{
switch(tabID)
{
case 0:
[btn1 setSelected:true];
[btn2 setSelected:false];
[btn3 setSelected:false];
[btn4 setSelected:false];
break;
case 1:
[self hideButtons]; //Call function for hiding buttons like this.
[btn1 setSelected:false];
[btn2 setSelected:true];
[btn3 setSelected:false];
[btn4 setSelected:false];
break;
}
self.selectedIndex = tabID;
}
Let say you want to hide buttons on 2nd View Controller. So I have called [self hideButtons] in case 1 index.
This will Hide all the tabbar buttons. And again Viceversa you have to put diff condition to show those tab buttons.
Does this make sense ?
Since the custom tabs exists already at the point this method is called. You should assign it to detailView's customTabs property here.
- (IBAction) openFourth:(id)sender{
detailVC * detailView = [[detailVC alloc] initWithNibName:#"detailVC" bundle:nil andSender:kFourthButtonSender];
detailView.customTabs = **theExistingCustomTabsObject**;
[self.navigationController pushViewController:detailView animated:YES];
[detailView release];
}
Orignal Answer
As the reference to the subclass of the UITabBarController is nil, you will have to set it properly. If you have used IB to set the view controllers, go to the NIB file. Right click on the view controller, select the customTabs outlet and connect it to the customTabBar object holding the view controllers.
If you've created the view controllers programmatically then somewhere after adding the view controllers to the tab bar and before releasing the view controllers, do this,
viewController.customTabs = self.customTabBarObject;
Ive got an iPhone/iPad universal application and I wanted to have a custom navigation bar where the top half of the nav bar contained our companies logos, and the bottom half was the standard navigation bar.
I figured out how to do this, showing in the code below, but my UIButton "logosButton" doesnt always respond to being clicked, it appears as though only certain parts of the button are active, and others dont do anything at all... I cannot figure out why this is.
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview: navController.view];
float width = IS_IPAD ? 768.0f : 320.0f;
float logosHeight = IS_IPAD ? 20.0f : 20.0f;
float barHeight = IS_IPAD ? 32.0f : 32.0f;
self.navBar = [[UINavigationBar alloc] initWithFrame: CGRectMake(0.0f, logosHeight, width, barHeight)];
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, logosHeight)];
UIButton *logosButton = [[UIButton alloc] init];
[logosButton setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState:UIControlStateNormal];
[logosButton setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState:UIControlStateHighlighted];
[logosButton addTarget:self action:#selector(logosButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[logosButton setFrame: CGRectMake(0, 0, width, logosHeight)];
[tempView addSubview: logosButton];
[[self view] addSubview: tempView];
[tempView release];
[[self view] addSubview: self.navBar];
self.navItem = [[UINavigationItem alloc] initWithTitle: #"Home"];
[self.navBar pushNavigationItem:self.navItem animated:NO];
}
The method: logosButtonClicked does get fired every now and then when I click on the UIButton, but I clearly am clicking on certain spots where nothing happens at all...
Very frustrating, I dont seem, to see a pattern in regards to where its active, but could someone please help out here?
EDIT
I think I have just stumbled across something, I changed the button to a UIButtonTypeRoundedRect and got rid of the images (and also made it larger) and it appears that I cannot click on the bottom OR top sections of the button where the button is rounded. So the middle rectangular section is the only section where I can click... why would this be?
EDIT 2
For anyone reviewing this question, please see taber's latest edit on his answer. The Navigation Controller is eating touches for some reason, and I need to figure out why this is so, could be a bug?
FINAL ANSWER :)
Okay after reviewing the project it looks like the UINavigationController that is positioned below the button is eating touches globally. Which is definitely weird because it was added as a subview BELOW your button. So there must be some kind of funky frame/touch-eating going on with the UINavigationController. I tried to set navigationController.titleView.userInteractionEnabled = NO but to no avail. If anyone knows how to basically make UINavigationController and UINavigationBar not eat touches (I'm talking about the background where no buttons exist) then please chime in. The UIButton touches work just fine when the UINavigationController isn't added to the view.
Original Answer
It may be some other UI elements in [self view] or tempView sitting on top of the button and intercepting taps. You might want to try either commenting out everything else in the view(s) and/or try setting the userInteractionEnabled property on them like this:
[otherUIElement setUserInteractionEnabled: NO];
EDIT:
This code makes it so that you CAN click the round rect edges but NOT the title text. So I suspect that it's some sort of subview preventing the button from catching the tap.
[logosButton addTarget:self action:#selector(logosButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[logosButton setFrame: CGRectMake(0, 0, 320.0, 50.0)];
[logosButton setTitle: #"HELLO" forState: UIControlStateNormal];
[logosButton.titleLabel setUserInteractionEnabled: YES];
EDIT #2:
Try using this subclassed button and see if the issue still occurs:
// NavBtn.h
#interface NavBtn : UIButton {
}
-(id)initWithTitle:(NSString *)text;
#end
// NavBtn.m
#import "NavBtn.h"
#implementation NavBtn
- (id)initWithTitle:(NSString *)text {
if ((self = [super initWithFrame: CGRectMake(0, 0, 320, 50)])) {
[self setTitle: text forState: UIControlStateNormal];
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
[self setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState: UIControlStateNormal];
[self setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState: UIControlStateHighlighted];
}
return self;
}
// i guess you shouldn't need to mess with layoutSubviews
#end
To load it into your view:
#import "NavBtn.h"
... in viewDidLoad, etc ...
NavBtn *btn = [[NavBtn alloc] initWithTitle: #"hey"];
[self.view addSubview: btn];
[btn release];
If THAT doesn't work, there's got to be some kind of third party library doing some funky category overriding of your UIButton class or something.