I have a button that pretty much takes an entire xib so that I can push another viewController on the screen if any part of the original view is touched. I've created an IBOutlet to this button and it works great, however I don't want the entire window to turn "blue" when it is touched (similar to when a small button is pressed). I've tried the following two methods that I found in a similar SO post: How can I prevent a UIButton from highlighting when pressed?, but neither method works. Is there something else I need to set up?
- (void)viewDidLoad
{
[super viewDidLoad];
self.entireWindowButton.adjustsImageWhenHighlighted = NO;
[self.entireWindowButton setImage: [self.entireWindowButton imageForState:UIControlStateNormal] forState:UIControlStateHighlighted];
}
I realise this is old question but if you set the UIButtons type to custom then "adjustsImageWhenHighlighted = NO" will work and it is set to NO by default.
Related
I've ran into an interesting and strange question while messing around with a project.
After spending like 3 hours doing it, I found out you can't change the view of the UIBackBarButtonItem, only the UILeftBarButtonItem, so if I want to implement a custom back button, I hide the UIBackButtonItem and display a UILeftBarButtonItem which does the popping.
Now I find it odd, that you can't change the UIBackBarButtonItem's view, but you can change the UILeftBarButtonItem and the UIRightBarButtonItem's views.
Can someone explain me why would Apple do this?
Actually, you can. Use UIBarButtonItem's instance method setBackButtonBackgroundImage:forState:barMetrics:.
So if you want to change the background image for all your back buttons, your code should like something like:
UIImage *backButtonBgImageNormal = [[UIImage imageNamed:#"back_button_bg.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(5, 15, 5, 5);];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonBgImageNormal forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Use delegate method of UINavigationController, such like
#pragma mark -
#pragma mark - UINavigationController Delegate Methods
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//// customize you own stuff here;
UINavigationBar *morenavbar = navigationController.navigationBar;
UINavigationItem *morenavitem = morenavbar.topItem;
morenavitem.rightBarButtonItem.tintColor = [UIColor blackColor];
}
I think I have a comprehensive solution for you.
1) From experience, it's just best to not bow to limitations of BarButtonItems. I suggest you create a simple UIButton, customise it to your liking. maybe add an action to its touch events..brand it with custom background and title colors...etc.. keep a reference to this button, maybe as a property.
2) Then, you create an instance of UIBarButtonItem using the UIBarButtonItem initializer -initWithCustomView, you sneak in the UIButton instance as this custom view in the init and have complete control over it.
3) Finally, you just do this.
self.navigationItem.LeftBarButtonItems = #[ourUIBarButtonItem].
The navigation bar has an Array property "leftBarButtonItems" for series of left buttons, and rightBarbuttonItems for the right side. Just replace this with your own array, containing the UIbarButtonItem, that containing your button, and you having a reference to your button.
And now you can completely control you button that is properly in the navigation bar.
NOTE! - Once you provide such a leftBarButtonItem, the stock Apple BackButton is gone.
I'm trying to add a button to a view programmatically and I'd like it to stay "pushed in" when clicked, until it is clicked again. From what I've read it seems like the button to use for this would be NSPushOnPushOffButton. Here's Apple's discription for it:
The first click both highlights and causes the button to be “pushed
in” if the button is bordered; a second click returns it to its normal
state. This option is called “Push On Push Off” in Interface Builder’s
Button Inspector.
It wasn't working in my program so I made a SSCCE, which I'll include below. My problem is the button isn't staying in when clicked, but rather popping back out like a normal button. I'm not sure if I'm missing something about how this button is supposed to perform or if I'm simply implementing it incorrectly (This is the first time I've tried to do a UI programmatically), but other button types such as NSToggleButton work so unless there is something special about NSPushOnPushOffButton I don't see where I went wrong. if someone could suggest a better solution or explain where I went wrong that would be great. Thanks!
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSRect buttonFrame = NSMakeRect(0,0,200,200);
NSButton *button = [[NSButton alloc]initWithFrame:buttonFrame];
[self.window.contentView addSubview:button];
[button setButtonType:NSPushOnPushOffButton];
}
#end
It seems that you have to set a "bezel style", for example
[button setBezelStyle:NSRegularSquareBezelStyle];
After adding that to your sample code, it worked as expected.
I have an UIWebView loaded with div, act as editor to write. Now i am adding UIWebView as sub view on UIWindow to set the frame equal to full screen and to hide the UIKeyboard, but at some button method, i need to get UIWebview from UIWindow and sent it back to UIKeyboard. Here is my code which is not working:
keyboardWindowFrame= nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows])
{
if (![[testWindow class] isEqual:[UIWindow class]])
{
keyboardWindowFrame = testWindow;
[webViewForEditing setFrame:CGRectMake(5, 63, 310, 400)];
[webViewForEditing.scrollView setContentSize:CGSizeMake(310, 400)];
[keyboardWindowFrame addSubview:webViewForEditing];
break;
}
}
- (IBAction)keyboardButtonSelected:(id)sender
{
[keyboardWindowFrame sendSubviewToBack:webViewForEditing]; //need to send UIWebView back to UIWindow so i can write
}
I think I am trying to do the same thing as you and so although your question is not particularly clear hopefully my answer will help.
It seems that you have a view 'webViewForEditing' which you want to add and bring in front of the keyboard. When you click a button you want to put this view behind the keyboard again.
I have also tried using the sendSubViewToBack code with no joy.
In the end though I managed to get it to work using:
[[self view] exchangeSubviewAtIndex: withSubviewAtIndex: ];
(Credit goes to Sunny with it adapted from a question here)
I used the following code below, with to switch between a UIView and the keyboard:
- (IBAction)toggleButtonPressed:(id)sender {
UIWindow * window = [UIApplication sharedApplication].windows.lastObject;
if (window.subviews.count == 1) {
[window addSubview:_menuView];
}
else {
[window exchangeSubviewAtIndex: 0 withSubviewAtIndex: 1];
}
}
I am only working with two views (_menuView and the keyboard) which means I check how many subviews my window has to make sure I only add _menuView once.
Then it is easy to exchange the two views.
Even if you had more subviews in your window I am sure you could use a modified version of this. As long as none of your other views change places then exchanging them will always switch the same two views.
NOTE: As an aside. I am not sure if this code works if called when the keyboard is not first responder. I get the variable for Window using the last object in the window, which is always the keyboard if it has been made first responder. It might need tweaking to get it working at other times.
I formulated another, more eloquent, answer while working on this:
Add the views you want to the window view that holds the keyboard view:
#interface BViewController : UIViewController {
UIWindow * window;
}
// Add the code when the keyboard is showing to ensure it is added while we have a keyboard and to make sure it is only added once
-(void) keyboardDidShow: (NSNotification *) notification {
window = [UIApplication sharedApplication].windows.lastObject;
if (window.subviews.count == 1) {
[window addSubview:_menuView];
[window addSubview:_gameView];
[window addSubview:_stickerView];
[self hideViews];
}
}
- (void)hideViews {
_menuView.hidden = YES;
_gameView.hidden = YES;
_stickerView.hidden = YES;
}
So now we have our UIWindow view which contains our views and also our keyboard. They are all hidden so our keyboard appears at the front and can be typed on.
Now use a simple function to decide which view to bring in front of the keyboard:
- (void)bringViewToFront: (UIView *)view {
[self hideViews];
view.hidden = NO;
}
Hiding the views makes sure we only have our correct view at the front.
I spent a lot of time thinking how we could move different views forward and back, using the exchange function. Actually using hide and reveal means we can get our view immediately and still easily have access to the keyboard by hiding all the views.
I've seen a lot of info on changing the button image for selected but being a new I'm having a bit of trouble implementing a simpler version of it.
When the button is pressed it goes dark and I would like it to stay that way once it's been selected. So there are a few questions.
Do I create IBOutlet for the button and then and IBAction to change the state with something like button.state = SELECTED.
Sorry for the complete lack of any code to look at.
Edit: (id)sender is the button object right?
-(IBAction)journalEntryViewControllerClick: (id)sender
{
UIButton *button = (id)sender;
[button setSelected:YES];
}
You can set separate image for button's selected state (UIControlStateSelected) and in button action you can toggle its state:
- (void) btnAction:(UIButton*)button{
button.selected = !button.selected;
}
Yes that could be one way of doing it. If you want a "stateswitch" kind of look.
However you set the button.selected = YES;
You probably want a UISegmentedControl instead. UIButton's are meant to be momentary.
When an UITextField is firstResponder, I would like to bring to front an UIDatePicker (bottom part of the screen) without the "going down keyboard" (no call to UITextField resignFirstResponder).
The aim is to process like UIKeyboard of UITextField which pop-up on nearly everything when it becomeFirstResponder. modalViewController seems to be fullscreen only.
- showDatePicker:(id)sender {
if([taskName isFirstResponder]) [taskName resignFirstResponder];
[self.view.window addSubview: self.pickerView];
// size up the picker view and compute the start/end frame origin
(...)
[UIView commitAnimations];
}
This example is an animation of keyboard going down, and DatePicker going up, behind and not in front.
Do you know a solution ? A piece of code would be welcome. Thanks in advance.
This is simply done by setting the input view of the text field to the Picker View. Then, on Editing did begin tell the picker view to becomeFirst responder. Like this
textField.inputView = pickerView
then using an IBAction called when the Editing Did Begin
-(IBAction) setPickerViewAsFirstResponder:(id)sender
{
[pickerView becomeFirstResponder];
}
This works perfectly. You'll need to implement code to actually set what the picker view is currently showing to be a string in the text field still.
This definitely can be done... simply implement the method below after setting UIViewController <UITextFieldDelegate> in your .h
Long story short, this overrides the keyboard loading before text editing begins.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// Make a new view, or do what you want here
UIDatePicker *pv = [[UIDatePicker alloc] initWithFrame:CGRectMake(0,245,0,0)];
[self.view addSubview:pv];
return NO;
}