UIToolbar precise size - ios

I'm trying to customize my NavigationBar with the help of a toolbar.
I've implemented it programmatically as follows:
UIToolbar* tools = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 100, 44.01)];
and then I added it to my NavigationBar. The problem is that I have this ugly effect on the borders:
I've tried to change the y and the height values, with no results.
Do you have any ideas to avoid this?
Thanks in advance, yassa

I wouldn't do it this way.
You can achieve the same effect by adding a view with 2 buttons to the navigationItem.rightBarButtonItem. it is very simple:
// view that will hold the buttons
UIView* container = [[UIView alloc] init];
// create 1 button and add it to the container
UIButton* button = [[UIButton alloc] init........];
[container addSubview:button];
//create 2 button and add it to the container
button = [[UIButton alloc] init.........];
[container addSubview:button];
// now create a Bar button item
UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:container];
// set the nav bar's right button item
self.navigationItem.rightBarButtonItem = barButtonItem;

I partially agree with previous answers and comments.
The solution you suggested works fine for custom buttons. But what if I want to implement standard Edit button?
Access to the standard buttons/icons is through the UIBarButtonItem class, not UIButton. And you can't add UIBarButtonItem objects to a UIView.
After many research on the web, I've found the solution that completely cover my requirement. The toolbar must be created in the following way:
UIToolbar *tools = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 95.0f, 44.01f)];
tools.tintColor = self.navigationController.navigationBar.tintColor;
tools.barStyle = -1;
And this is the result:
Hope it helps!
yassa

Or you can do it in this way.
Just create new subclass of UIToolbar like this
#interface MyToolbar : UIToolbar
#end
#implementation MyToolbar
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
self.clearsContextBeforeDrawing = YES;
}
return self;
}
- (void)drawRect:(CGRect)rect {
// do nothing
}
- (void)dealloc {
[super dealloc];
}
#end
And use it as normal UIToolbar. I don't know why but it just works.

Related

Add buttons to the left and right of the searchbar

I want a searchbar that has a button on the left of the text field, and on the right. Identical to the searchbar found on the current Alien Blue reddit app.
So far, the closest thing I have to achieving this is that I have been able to change the text of the "Cancel" button on the right side using this line of code.
[self.searchController.searchBar setValue:#"Hello" forKey:#"_cancelButtonText"];
But that doesn't really help since I want the right side to open up different search options, not cancel the search.
Help me ____, you're my only hope
Put the effect first
//RWSearchBar.h
#define BarFrame CGRectMake(100, 20, 200, 44)
#import <UIKit/UIKit.h>
#interface RWSearchBar : UISearchBar
#end
//RWSearchBar.m
#import "RWSearchBar.h"
#implementation RWSearchBar
- (void)layoutSubviews {
self.frame = BarFrame;
}
#end
//RWViewController.m
#import "ViewController.h"
#import "RWSearchBar.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
RWSearchBar *searchBar = [[RWSearchBar alloc] init];
[self.view addSubview:searchBar];
CGRect aFrame = BarFrame;
UIButton *leftBtn = [[UIButton alloc] initWithFrame:CGRectMake(aFrame.origin.x - 60, aFrame.origin.y, 60, 44)];
leftBtn.backgroundColor = [UIColor blueColor];
UIButton *rightBtn = [[UIButton alloc] initWithFrame:CGRectMake(aFrame.origin.x + aFrame.size.width, aFrame.origin.y, 60, 44)];
rightBtn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:leftBtn];
[self.view addSubview:rightBtn];
}
You can custom more visual effect by yourself.

How to remove a programmatically created subview by pressing a button within the subview

I currently have a barbutton:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneDate:)];
It calls the following action:
- (IBAction)doneDate:(id)sender{
[self removeDateView]
}
Which calls the following method:
- (void)removeDateView{
NSLog(#"subviews of view3.view: %#",self.View3.subviews);
[self.View3.subviews. makeObjectsPerformSelector: #selector(removeFromSuperview)];
}
The subview that I'm trying to remove is
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
At the moment it just deletes everything within that View, I can't seem to remove the view called containerView which has the datepicker and toolbar.
As erhnby stated, you could use a tag - which is a great method, but I always try to shy away from looping through a view's subviews whenever I can. Personally, I would make the view you are going to remove an instance variable, and when you want to remove it you can call remove directly on it... Just made a simple example that does this:
.h file:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController {
UIView *_containerView;
}
#end
.m file:
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (id)init {
self = [super init];
// create the bar button and set it as the right bar button on the navigation bar
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(removeDoneDate)];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// create the container view and add it as a subview
_containerView = [[UIView alloc] initWithFrame:CGRectMake(20, 100, 100, 100)];
_containerView.backgroundColor = [UIColor redColor];
[self.view addSubview:_containerView];
}
- (void)removeDoneDate {
// remove it
[_containerView removeFromSuperview];
}
#end
Results in this to start:
Press button...
(sorry, didn't realize the white on white would be that hard to see)
set tag for that will remove view
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
[containerView setTag:100];
and find it and removeFromSuperView
for (UIView* view in self.View3.subviews) {
if ([view isKindOfClass:[UIView class]] && view.tag == 100) {
[view removeFromSuperview];
}
}

Adding a UISegmentedControl under NavigationBar

I’m adding a UISegmentedControl right under the NavigationBar in a UITableViewController. This is the code.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationBar = self.navigationController.navigationBar;
UIView *segmentView=[[UIView alloc] initWithFrame:CGRectMake(0, self.navigationBar.frame.size.height, self.navigationBar.frame.size.width, 50)];
[segmentView setBackgroundColor:[UIColor whiteColor]];
segmentView.alpha = 0.95;
self.tabSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Favourites", #"All", nil]];
self.tabSegmentedControl.frame = CGRectMake(20, 10, self.navigationBar.frame.size.width - 40, 30);
[self.tabSegmentedControl addTarget:self action:#selector(tabChanged:) forControlEvents:UIControlEventValueChanged];
[segmentView addSubview:self.tabSegmentedControl];
[self.navigationBar addSubview:segmentView];
[self.tabSegmentedControl setSelectedSegmentIndex:1];
}
The view and the SegmentedControl appear on the screen well, but they are not clickable. The selector doesn’t get executed when tapped on the SegmentControl; it doesn’t even switch tabs! In fact, the stuff that is underneath the segmentView (items in the TableView) get clicked when you tap on it. I have tried but failed to understand why this is happening! Any suggestions would be helpful!
You are adding a view below the bounds of its super view. You may see the view however you cannot click it because it is out of bounds. If you set the property of the navigation bar clipsToBounds to YES you should see that the view disappears. What you need to do is add the segment controller to the table view. Here is an example:
- (void)viewDidLoad
{
[super viewDidLoad];
...
[self.view addSubview: self.segmentView]; // need to keep a pointer to segmentView
self.tableView.contentInset = UIEdgeInset(self.segmentView.frame.size.height, 0,0,0);
}
-(void) scrollViewDidScroll:(UIScrollView*) scrollView{
CGRect rect = self.segmentView.frame;
rect.origin = self.tableView.contentOffset;
self.segmentView.frame = rect;
}

UISearchBar Refuses to Change Width?

I am adding a UISearchBar to a UINavigation Bar as so (this is a storyboard based app) :
//Setup the search bar.
searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 50.0f, 44.0f)];
self.tabBarController.navigationItem.titleView = searchBar;
searchBar.delegate = self;
controller = [[UISearchDisplayController alloc]initWithSearchBar:self.searchBar contentsController:self];
controller.searchResultsDataSource = self;
controller.searchResultsDelegate = self;
No matter what I set the width and height and position of the search bar to be, it will not change the height / width of the search bar. It is always the same width and height.
Can anyone suggest how to alter ?
I've experienced the same problem one time, and what I did was adding the searchBar into a container View (i've had problems showing the cancel button) and add the container view as a left bar item
- (UIBarButtonItem *)createSearchBarHolder {
UIView *searchBarContainer = [[UIView alloc] initWithFrame:navigationSearchBar.frame];
searchBarContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[searchBarContainer addSubview:navigationSearchBar];
navigationSearchBar.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
UIBarButtonItem *searchBarHolder = [[UIBarButtonItem alloc] initWithCustomView:searchBarContainer];
return searchBarHolder;
}
And in viewDidLoad:
NSArray *leftBarButtons = [[NSArray alloc] initWithObjects:[self createSearchBarHolder], nil];
self.navigationItem.leftBarButtonItems = leftBarButtons;
It's not clear what size you want your search bar to be. If you make it the navigation item's titleView, it will adjust for any buttons on the navigation bar, and adjust on rotation. Is that what you want?
- (void)viewDidLoad {
[super viewDidLoad];
UISearchBar *sb = [[UISearchBar alloc] init];
self.navigationItem.titleView = sb;
}

creating a UIToolbar programmatically

I wish to add a UIToolbar programmatically to a view when a user clicks on a button (in my case when they zoom in on a photo).
It seems to work fine when I create the toolbar in the click method and add to the subview but if I create the toolbar in the viewDidLoad method, assign it to an instance variable,and add that instance variable later to the subview on click, nothing appears. The debugger shows that the instance variable is a UIToolbar and is not null. I didn't want to create and destroy the same toolbar on every click so I thought it was better just to keep it as an instance variable that I add and remove from the view as needed. Is this the right approach?
Why is it visible in the one case and not the other.
Setup
#synthesize toolBar;
- (UIToolbar*)createToolbar
{
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.frame = CGRectMake(0, self.view.frame.size.height - 44, self.view.frame.size.width, 44);
UIBarButtonItem *shareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(sharePhoto:)];
NSArray *buttonItems = [NSArray arrayWithObjects:shareButton,nil];
[toolbar setItems:buttonItems];
return toolbar;
}
This works
- (void) clickMyButton {
toolBar = [self createToolbar];
[self.view addSubview:toolBar];
}
This doesn't show anything
- (void)viewDidLoad
{
[super viewDidLoad];
toolBar = [self createToolbar];
}
- (void) clickMyButton {
[self.view addSubview:toolBar];
}
Why doesn't it work in the latter case
The problem is that when viewDidLoad gets called, it is not guaranteed that the frames for your view and subviews are set. Try calling [self createToolbar] from viewWillAppear or viewDidAppear instead.

Resources