UISlider in UIToolbar -> can't get slider.value and process it. iOS SDK - objective-c

I'm trying to get a UISlider into my UIToolbar and to take the value from it and process it. I also want to be able to change the slider.value via other methods.
So, I set it up for the UISlider by it's self (not on a UIToolBar) and everything worked fine. Then, when I put it into the UIToolBar, the value stopped getting sent to and from it (I am NSLogging it whenever it changes and I keep getting 0 returned to me).
Here's the relevant section of my code - does anybody have any ideas?
- (void)setupToolBarAndSlider {
CGRect frame = CGRectMake(0.0, 0.0, 200.0, 30.0);
UISlider *slider = [[UISlider alloc] initWithFrame:frame];
[slider addTarget:self action:#selector(sliderValueChanged) forControlEvents:UIControlEventValueChanged];
[slider setBackgroundColor:[UIColor clearColor]];
slider.minimumValue = 0;
slider.maximumValue = 8;
slider.continuous = YES;
slider.value = questionNumberForArray;
//Change slider for UIToolbar
UIBarButtonItem *skipQuestionSlider = [[UIBarButtonItem alloc] initWithCustomView:slider];
// Set the width of aSlider
[skipQuestionSlider setWidth:400.0];
//Set up UIToolBar with Slider in it.
UIToolbar *toolBar;
CGRect rect2 = CGRectMake(0, toolBar.frame.origin.y , self.view.frame.size.width , 44);
toolBar = [[UIToolbar alloc]initWithFrame:rect2];
toolBar.barStyle = UIBarStyleBlackTranslucent;
[toolBar setItems:[NSArray arrayWithObjects:skipQuestionSlider, nil]];
[self.view addSubview:toolBar];
}
- (void)sliderValueChanged {
NSInteger roundedSliderNumber = round(skipQuestionSlider.value);
NSLog(#"Slider Value = %d", roundedSliderNumber);
}
Sam

A UIBarButtonItem (in your case, skipQuestionSlider) does not have a value property, it just houses the item. You need to reference the item you put in the UIBarButtonItem.
NSInteger roundedSliderNumber = round(slider.value);

Related

UINavigationBarButton not working when using customView

I would like to make a custom UIBarButtonItem that contains both image and text and also customise(reduce) the UIButton tap area. To achieve this programmatically, I am using the following code snippet. But UIButton disappears when added in UIView as subview. Could somebody guide me what is wrong ?
To reduce tap area of bar button, I am embedding custom UIButton in custom UIView.
//Set Navigation Bar
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
//Set title if needed
UINavigationItem * navTitle = [[UINavigationItem alloc] init];
navTitle.title = #"";
UIView *customBackView = [[UIView alloc] initWithFrame:CGRectMake(220,0,50,40)];
customBackView.backgroundColor = [UIColor clearColor];
//Here you create info button and customize it
UIButton * tempButton = [UIButton buttonWithType:UIButtonTypeSystem];
tempButton.frame=CGRectMake(240,2,40,40);
[tempButton setImage:[UIImage imageNamed:#"offline_bk.png"]
forState:UIControlStateNormal];
//Add selector to info button
[tempButton addTarget:self action:#selector(onTapDone:) forControlEvents:UIControlEventTouchUpInside];
[customBackView addSubview:tempButton];
[customBackView bringSubviewToFront:tempButton];
UIBarButtonItem * infoButton = [[UIBarButtonItem alloc] initWithCustomView:customBackView];
//In this case your button will be on the right side
navTitle.rightBarButtonItem = infoButton;
//Add NavigationBar on main view
navBar.items = #[navTitle];
[self.view addSubview:navBar];
Because your tempbutton is going out of bound of custom back view. You set the y origin value to 2 and x origin value to 240 which is causing button to go out of bound of custom back view.
Try this code:
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
//Set title if needed
UINavigationItem * navTitle = [[UINavigationItem alloc] init];
navTitle.title = #"";
UIView *customBackView = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,50)];
customBackView.backgroundColor = [UIColor clearColor];
//Here you create info button and customize it
UIButton * tempButton = [UIButton buttonWithType:UIButtonTypeSystem];
tempButton.frame=CGRectMake(4,2,40,40);
[tempButton setImage:[UIImage imageNamed:#"offline_bk.png"]
forState:UIControlStateNormal];
//Add selector to info button
[tempButton addTarget:self action:#selector(onTapDone:) forControlEvents:UIControlEventTouchUpInside];
[customBackView addSubview:tempButton];
[customBackView bringSubviewToFront:tempButton];
UIBarButtonItem * infoButton = [[UIBarButtonItem alloc] initWithCustomView:customBackView];
//In this case your button will be on the right side
navTitle.rightBarButtonItem = infoButton;
//Add NavigationBar on main view
navBar.items = #[navTitle];
[self.view addSubview:navBar];
[self.view bringSubviewToFront:navBar];

iOS 7 BarButtonItem with image and title

I'm trying to figure out how can I achieve something like this:
This is a toolbar and I'd like to keep the button title text without having to create the whole image with icon AND text. How can I add the icon to the left of the UIBarButtonItem while keeping the text set with:
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Button" style:UIBarButtonItemStyleBordered target:nil action:nil];
EDIT
This is what I achieved with the following code:
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setImage:[UIImage imageNamed:#"Test"] forState:UIControlStateNormal];
[customButton setTitle:#"Button" forState:UIControlStateNormal];
customButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
[customButton sizeToFit];
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
Two issues here: the first is the size of the UIButton and the second is that, as you can see from the gif, the button doesn't animate properly when I tap inside the button and when I release the tap. Any ideas?
You can embed a UIButton as a custom view inside your UIBarButtonItem. You can create your UIButton however you want, including with an image and text, using -setImage:forState: and -setTitle:forState:.
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setImage:[UIImage imageNamed:#"image"] forState:UIControlStateNormal];
[customButton setTitle:#"Button" forState:UIControlStateNormal];
[customButton sizeToFit];
UIBarButtonItem* customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.leftBarButtonItem = customBarButtonItem; // or self.navigationItem.rightBarButtonItem
Note that when doing this, you'll need to attach your IBAction methods to customButton, not to customBarButtonItem.
For more info, see the documentation for initWithCustomView:.
You can also do all of this in interface builder just by dragging a UIButton to the left bar button/right bar button slot on a navigation bar.
I was not satisfied with all solutions found on stack overflow becauseI like how UIBarButtonItenm convert images so they are displayed correctly and they can be changed with tint colour. So i discovered this solution that I can use nicely with not much code... End effect is similar to toolbar in facebook and other current apps...
When you change tint colour of view contained in UIBArButtonItem colours of image and title change accordingly, really cool , I do not have to create special images at all.
This code is called from each button like that Competition Button, and also Button is set as referencing outlet...
- (void)selectButton:(UIButton *)sender {
_competitionButton.superview.tintColor = [UIColor lightGrayColor];
_usersButton.superview.tintColor = [UIColor lightGrayColor];
_managementButton.superview.tintColor = [UIColor lightGrayColor];
sender.superview.tintColor = [UIColor whiteColor];
}
- (IBAction)onCompetitionButtonClick:(UIButton *)sender {
[self selectButton:sender];
[_scrollView scrollToPage:0 of:3];
}
In Button like that titled Competition there is only title and in bar button item there is image... This is how I have setup it and it works , maybe there are also other possibilities..
So I managed to do my solution programatically... Some users where complaining it does not work ... So how to create UTToolbar with image and item so that you can change color of button by tint and it magically alters image as well as title label ? My UI editor solution works for sure...
In this code can clarify things more and you can do it programatically either...
- (void)loadToolbar {
NSMutableArray *items = NSMutableArray.new;
[items add:[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]];
for (uint pageIndex = 0; pageIndex < _controllers.count; ++pageIndex) {
UIView *itemView = [UIView.alloc initWithFrame:CGRectMake(0, 0, 100, 44)];
itemView.backgroundColor = [UIColor clearColor];
itemView.tintColor = [UIColor orangeColor];
[itemView addSubview:[self createToolbarForItemView:pageIndex]];
[itemView addSubview:[self createButtonForItemView:pageIndex]];
UIBarButtonItem *item = [UIBarButtonItem.alloc initWithCustomView:itemView];
item.style = UIBarButtonItemStylePlain;
[items add:item];
[items add:[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]];
}
[_toolbar setItems:items];
}
- (UIButton *)createButtonForItemView:(uint)pageIndex {
UIButton *itemButton = [UIButton buttonWithType:UIButtonTypeSystem];
itemButton.frame = CGRectMake(0, 0, 100, 44);
itemButton.titleLabel.font = [UIFont systemFontOfSize:11];
itemButton.contentEdgeInsets = UIEdgeInsetsMake(30, 0, 0, 0);
itemButton.text = [_controllers[pageIndex] tabTitle];
itemButton.touchUp = ^(UIButton *sender) {
for (UIButton *button in _buttons) button.superview.tintColor = UI.toolBarInactiveButtonTextColor;
sender.superview.tintColor = UI.toolBarActiveButtonTextColor;
[self showPage:pageIndex];
};
[_buttons add:itemButton];
return itemButton;
}
- (UIToolbar *)createToolbarForItemView:(uint)pageIndex {
UIToolbar *itemToolbar = [UIToolbar.alloc initWithFrame:CGRectMake(0, 0, 100, 44)];
itemToolbar.tintColor = nil;
itemToolbar.barStyle = _toolbar.barStyle;
itemToolbar.translucent = _toolbar.translucent;
UIBarButtonItem *imageItem = [_controllers[pageIndex] tabImageItem];
imageItem.style = UIBarButtonItemStylePlain;
imageItem.tintColor = nil;
imageItem.imageInsets = UIEdgeInsetsMake(-10, 0, 0, 0);
itemToolbar.items = #[
[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil],
imageItem,
[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]
];
return itemToolbar;
}
I solved this problem as follows:
[Button **setTitleColor**:[UIColor colorWithRed:129/255.0f green:124/255.0f blue:110/255.0f alpha:1.0f] forState:**UIControlStateHighlighted**];

iOS7 excessive navigationbar button padding

I'm experiencing excessive UIBarButtonItem padding/spacing when using the LeftBarItems and RightBarItems (see image below). The icons used on the UIBarButtonItems do not contain extra padding. So I would like to know what's causing this?
I use this in order to remove space before the first item.
However it doesn't work between system items like UIBarButtonSystemItemAdd, only with UIBarButtonItem that has an image.
#interface UIBarButtonItem (NegativeSpacer)
+(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width;
#end
#implementation UIBarButtonItem (NegativeSpacer)
+(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width {
UIBarButtonItem *item = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil
action:nil];
item.width = (width >= 0 ? -width : width);
return item;
}
#end
Use it like this:
UIBarButtonItem *item0 = [UIBarButtonItem negativeSpacerWithWidth:13];
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"sidebar.png"]
style:UIBarButtonItemStylePlain
target:vc
action:#selector(sideMenuAction:)];
NSArray* items = #[item0, item1];
[vc.navigationItem setLeftBarButtonItems:items animated:NO];
[vc.navigationItem setLeftItemsSupplementBackButton:YES];
You can move the image
self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25);
Apple silently increased the horizontal spacing constraints for UIBarButtonItems and sadly, still hasn't added any UIAppearance methods to adjust the horizontal positioning of UIBarButtonItems.
The best solution (which worked for me) is to wrap your UIBarButtonItems in a UIView using initWithCustomView: and adjust the bounds of that custom view to get your desired positioning. Here's a good answer on how to do this.
If you want to take things a step further, you can create a category on UIBarButtonItem with class methods that return the bar buttons you use throughout your app. That way, when you a need a bar button, you can call something like:
self.navigationItem.leftBarButtonItem = [UIBarButtonItem mySearchBarButtonItemWithTarget:self selector:#selector(search)];
There are two kinds of button on the navigation bar in iOS 7: button with image and button with text. I wrote a class to do it. Here is how:
GlobalUICommon.h:
#interface UIBarButtonItem(CustomUIOfONE)
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action;
+ (UIBarButtonItem*)barItemWithTitle:(NSString*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action;
#end
GlobalUICommon.m:
#implementation UIBarButtonItem(CustomUIOfONE)
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[button setImage:image forState:UIControlStateNormal];
[button setImage:highlightedImage forState:UIControlStateHighlighted];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[button setImageEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)];
}
UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return customUIBarButtonItem;
}
+ (UIBarButtonItem*)barItemWithTitle:(NSString*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:title forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[button.titleLabel setFont:[UIFont systemFontOfSize:15]];
[button setFrame:CGRectMake(0, 0, [button.titleLabel.text sizeWithFont:button.titleLabel.font].width + 3, 24)];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[button setContentEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)];
}
UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return customUIBarButtonItem;
}
#end
YourViewController.m:
Example for Button with Image:
UIBarButtonItem* leftButtomItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:#"yourImage"]
highlightedImage:[UIImage imageNamed:#"yourImage"]
xOffset:-11
target:self
action:#selector(yourHandler)];
self.navigationItem.leftBarButtonItem = leftButtomItem;
UIBarButtonItem* rightButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:#"yourImage"]
highlightedImage:[UIImage imageNamed:#"yourImage"]
xOffset:11
target:self
action:#selector(yourHandler)];
self.navigationItem.rightBarButtonItem = rightButtonItem;
Example for Button with Text:
self.navigationItem.leftBarButtonItem = [UIBarButtonItem barItemWithTitle:#"yourText" xOffset:-11 target:self action:#selector(yourHandler:)];
self.navigationItem.rightBarButtonItem = [UIBarButtonItem barItemWithTitle:#"yourText" xOffset:11 target:self action:#selector(yourHandler:)];
That's it.
I solved this by using storybord interface.
1.Select the Bar item.
2.Select the Size Inspector.
Here you can find image Inset,using top,bottom AND left , right you can change the position of Bar Item.
As #Luda comments, the solution is to
self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25);
However, #andrrs also points a problem here when inset is large: the hit area. In this case,we have to implement a way to setHitTestEdgeInsets. Below is an category method:
#implementation UIButton (Extensions)
#dynamic hitTestEdgeInsets;
static const NSString *KEY_HIT_TEST_EDGE_INSETS = #"HitTestEdgeInsets";
-(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets {
NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:#encode(UIEdgeInsets)];
objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIEdgeInsets)hitTestEdgeInsets {
NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
if(value) {
UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
}else {
return UIEdgeInsetsZero;
}
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) {
return [super pointInside:point withEvent:event];
}
CGRect relativeFrame = self.bounds;
CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
return CGRectContainsPoint(hitFrame, point);
}
#end

UINavigationBar - change UIBarButtonItem positions

I am using a UINavigationController and its bar within my app.
Now I want to change the leftBarButtonItem and rightBarButtonItem positions.
I want them to be on a different x and y position having a custom witdth and height.
But the problem is, that changing the frame does not change anything with the barButtonItem. I do not now why, but the frame always gets resetted to its original coordinates.
Here is my code which I call in viewWillAppear:
UINavigationItem *navItem = [[self.navigationBar items] lastObject];
UIView *rightview = [[UIView alloc] initWithFrame:CGRectMake(0,0,66,30)];
rightview.backgroundColor = [UIColor blueColor];
//add custom view
UIBarButtonItem *search = [[UIBarButtonItem alloc] initWithCustomView:rightview];
navItem.leftBarButtonItem = search;
The view is not starting at 0/0, the x position for example is at 5px insetead of 0.
Any suggestions on how to solve this issue?
This worked for me for the leftBarButtonItem:
If you want the UIBarButtonItem to show exactly at position (0, 0), you can create a UIButton, sets its frame to (-5, 0, width, height), assuming that the offet of a left barbutton item is (5, 0), and place that in a UIView that you set as leftBarButtonItem.
#import "UINavigationItem+CSAButtons.h"
#implementation UINavigationItem (CSAButtons)
- (void) makeLeftBarButtonWithTarget:(id)target action:(SEL)action {
UIImage * imageNormal = [UIImage imageNamed:#"normal.png"];
UIImage * imageHighlighted = [UIImage imageNamed:#"highlighted.png"];
UIImage * imageDisabled = [UIImage imageNamed:#"disabled.png"];
// create your button
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.exclusiveTouch = YES;
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:imageNormal forState:UIControlStateNormal];
[button setBackgroundImage:imageHighlighted forState:UIControlStateHighlighted];
[button setBackgroundImage:imageDisabled forState:UIControlStateDisabled];
// set the frame of the button (better to grab actual offset of leftbarbuttonitem instead of magic numbers)
button.frame = CGRectMake(-5.0, 0.0, imageNormal.size.width, imageNormal.size.height);
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, imageNormal.size.width, imageNormal.size.height)];
[view addSubview:button];
// set the barbuttonitem to be the view
UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:view];
self.leftBarButtonItem = barButtonItem;
}
I dont think you have the ability to move a UIBarButtonItem but you might be able to achieve the same effect by adding that UIView element as a subview to the navigationBar (or navItem). You'll need to play with it a bit. It should allow for much more flexibility.
hope this helps.

UINavigationController rightbarbuttonitem not showing

after going through the questions related to UINavigationController item i came to post my exact problem ..
firstly i am not add a UINavigationController in MainWindow.xib i created and adding UINavigationController in AppDelegate file
after that in a UIViewController (not in rootViewController) class I have to add a rightbarbutton of Done type I am
adding it in a searchbarDelegate Method showing as bold:-
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from teh detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(exhibDataObj.searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:#"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.theTableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
exhibDataObj.searching = true;
letUserSelectRow = NO;
self.theTableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:#selector(doneSearching_Clicked:)];
}
but this never works .
Any help will be more appreciable.
I've tested your code real quick and it seems to be working fine for me, however, I've had the same problem once back then it turned out I was setting the rightBarButtonItem to nil in my viewDidLoad method after setting it to a button. you should make sure your not making the same mistake somehow.
However if that does not work for you you can always try setting a custom button to it:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 30, 30)];
button.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"done.png"]];
[button addTarget:self action:#selector(doneButtonClicked) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationController.visibleViewController.navigationItem.rightBarButtonItem = customItem;