Custom titleView in UINavigationItem doesn't adjust height if offscreen during rotation - objective-c

I have a custom titleView for a UINavigationItem with the autoresizeMask set to adjust the width and height of the view. If I rotate the device while it is visible, the height is automatically adjusted for the shorter landscape nav bar. However, if I push a new view controller, rotate the device, and then come back to the one with the custom titleView, it doesn't recognize the change in height. For now I've added the following code to the viewWillAppear: method
- (void) viewWillAppear:(BOOL)animated {
CGRect frame = self.titleButton.frame;
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
frame.size = CGSizeMake(self.navigationController.navigationBar.frame.size.width - 150.0f, 44.0f);
} else {
frame.size = CGSizeMake(self.navigationController.navigationBar.frame.size.width - 150.0f, 32.0f);
}
self.titleButton.frame = frame;
...
}
This fixes the issue, but I'm wondering if I'm missing some property to get things adjusting on their own properly. The custom view is a UIButton:
titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[titleButton setFrame:CGRectMake(0, 0, self.navigationController.navigationBar.frame.size.width - 150.0f, 44.0f)];
[[titleButton titleLabel] setFont:[UIFont boldSystemFontOfSize:18]];
[titleButton setBackgroundImage:navbarButtonImage forState:UIControlStateNormal];
[titleButton setBackgroundImage:navbarButtonPressedImage forState:UIControlStateSelected];
[titleButton setBackgroundImage:navbarButtonPressedImage forState:UIControlStateHighlighted];
titleButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
titleButton.autoresizesSubviews = YES;
Is there a better way to setup this view?

Related

ChildView didn't maintain its ParentView Frame

Hope all of you will be fine. Guys i have a situation, I have a uiview and uibutton as under:
UIView* containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 70)];
containerView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:containerView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.backgroundColor = [UIColor redColor];
[button addTarget:self action:#selector(SettingPressed:) forControlEvents:UIControlEventTouchUpInside];
UIImage *image = [UIImage imageNamed:#"settings_button.png"];
[button setImage:image forState:UIControlStateHighlighted & UIControlStateNormal & UIControlStateSelected];
button.frame = CGRectMake(0,0, 40, 40);
button.center = containerView.center;
[containerView addSubview:button];
The problem is uibutton appear far from uiview instead of in the middle of uiview. What i am mistaking, please guide me.
Thanks.
First, when you change a view's center property the frame property will be changed automatically so you only should set the button center:
button.center = CGPointMake(containerView.frame.size.width / 2,
containerView.frame.size.height / 2);
Now, whenever you change the center property you need to manually tell the view to redraw itself using setNeedsDisplay :
[button setNeedsDisplay]
and lastly, the difference between frame and bounds that frame defines the position and size relative to the parent view while bounds describes the drawing area inside (or outside) the frame.

Adding UIPangesture for UIButton within UIScrollview to move over the all view

In my project i am having scroll at bottom and table at top.
Inside scrollview i am adding 10 buttons.for each button i had pan gesture to move around the screen.when the button intersect with table is will add a picture in tableview.
But the pan is working within the scroll.how to make it move over view
MY coding is:
downscroll=[[UIScrollView alloc]initWithFrame:CGRectMake(24, 635, 980, 100)];
downscroll.backgroundColor=[UIColor redColor];
downscroll.contentSize=CGSizeMake(990, 100);
[self.view addSubview:downscroll];
for(int i=1;i<=8;i++)
{
b1=[UIButton buttonWithType:UIButtonTypeCustom];
b1.frame=CGRectMake(30+px, 0, 80, 80);
[b1 setImage:[UIImage imageNamed: [NSString stringWithFormat:#"Icon%i.png",i]] forState:UIControlStateNormal];
[downscroll addSubview:b1];
// [self.view sendSubviewToBack:b1];
// [self.view bringSubviewToFront:b1];
[groupbutton addObject:b1];
panRecognizer3= [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(move:)];
[b1 setUserInteractionEnabled:YES];
b1.exclusiveTouch=YES;
img.tag=i;
[b1 addGestureRecognizer:panRecognizer3];
px=px+120;
}
When i add my buttons directly without scroll scrollview it works fine.But i need to add button scrollview
please help with proper code. Thanks in advance.
Here is the way I used in my application
In my code I follow the below steps
In UIPanGestureRecognizer starting point I add the button to the self.view from scrollView
Drag button by using the translationInView method
3.In UIPanGestureRecognizer end state I'll check if the button dropped in the destination View.If so do your required task else add the button at the same position in the scrollView
`MoveControl` is a UIPanGestureRecognizer method
- (void)MoveControl:(UIPanGestureRecognizer *)recognizer
{
UIButton *vew=(UIButton *)[recognizer view];
CGPoint newCenter = [recognizer translationInView:self.view];
if (recognizer.state==UIGestureRecognizerStateBegan) {
CGPoint point=vew.frame.origin;
[vew setTitle:NSStringFromCGPoint(point) forState:UIControlStateSelected];
CGRect rect=[self.view convertRect:[vew frame] fromView:[vew superview]];
[vew setFrame:rect];
[self.view addSubview:vew];
CGPoint point1=vew.frame.origin;
[vew setTitle:NSStringFromCGPoint(point1) forState:UIControlStateDisabled];
}
else
{
CGPoint oldcentre= CGPointFromString([vew titleForState:UIControlStateDisabled]);
CGRect rect=vew.frame;
CGPoint origin=rect.origin;
origin.x=(newCenter.x+oldcentre.x);
origin.y=(newCenter.y+oldcentre.y);
rect.origin=origin;
vew.frame=rect;
if (CGRectIntersectsRect(rect, [pageOriginalContainer frame])) {
[YourTable setBackgroundColor:[UIColor lightGrayColor]];//Notifying that the tableView will accept the icon
}
else
{
[YourTable setBackgroundColor:[UIColor clearColor]];
}
}
if (recognizer.state==UIGestureRecognizerStateEnded)
{
CGRect rect=[vew frame];
if (CGRectIntersectsRect(rect, [pageOriginalContainer frame])) {
//your method of adding the Image to table
}
else//else part is means for if user dropped dragging somewhere else other than Table
{
CGPoint point=CGPointFromString([vew titleForState:UIControlStateSelected]);
CGRect frame=vew.frame;
frame.origin=point;
vew.frame=frame;
[pageCopyContainer addSubview:vew];
// [NSFileManager defaultManager]
}
}
}

UIButton touch up inside event only fired if done in title

I am customizing a UITableViewCell with several subviews:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_mainView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40.0f)];
_hiddenOptionsView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40.0f)];
_menuView = [[CellMenuView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 20.0f)];
[self addSubview:_menuView];
[self addSubview:_hiddenOptionsView];
[self addSubview:_mainView];
}
return self;
}
The class CellMenuView is a UIView subclass which has two UIButtons with their counterpart target actions setup on initialization:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIImageView *background = [[UIImageView alloc] initWithFrame:frame];
[background setImage:[UIImage imageNamed:#"cell_menu_bg.png"]];
[self addSubview:background];
CGFloat buttonX = frame.origin.x;
CGFloat buttonY = frame.origin.y + 3.0f;
CGFloat buttonWidth = frame.size.width / 2.0f;
CGFloat buttonHeight = 10.0f;
_editButton = [UIButton buttonWithType:UIButtonTypeCustom];
_editButton.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight);
_editButton.backgroundColor = [UIColor clearColor];
_editButton.titleLabel.shadowColor = [UIColor blackColor];
_editButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.5f);
_editButton.titleLabel.font = [UIFont boldSystemFontOfSize:22.0f];
[_editButton setTitle:#"Edit" forState:UIControlStateNormal];
[_editButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_editButton addTarget:self action:#selector(editButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_editButton];
_fireButton = [UIButton buttonWithType:UIButtonTypeCustom];
_fireButton.frame = CGRectMake(buttonWidth, buttonY, buttonWidth, buttonHeight);
_fireButton.backgroundColor = [UIColor clearColor];
_fireButton.titleLabel.shadowColor = [UIColor blackColor];
_fireButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.5f);
_fireButton.titleLabel.font = [UIFont boldSystemFontOfSize:22.0f];
[_fireButton setTitle:#"Fire" forState:UIControlStateNormal];
[_fireButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_fireButton addTarget:self action:#selector(fireButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_fireButton];
return self;
}
}
I have implemented the target action methods but they aren't being executed. Instead, didSelectRowAtIndexPath: takes precedence over the touch up events inside buttons every time I pressed one of them.
The only way I have been able to fire the events on buttons is making sure that one of the letters in UIButton's title is touched (using the simulator, of course).
I must say that _menuView is hidden behind the other subviews and shown below the cell when a custom accessory button in cell is pressed. It appears by modifying the Y origin and disappears by setting it to 0.0f again.
I think it may be related to the view hierarchy, because I haven't had any problems in the past by adding buttons directly to the cell. But I'm just guessing here.
How can I make the events on buttons take precedence over the didSelectRowAtIndexPath: method?
Thanks!
Implement
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
And return nil for the indexPath you don't want selected; this will prevent didSelectRowAtIndexPath from being called on that cell, and (hopefully), your custom action will be called.
Update: After implementing this myself (adding borders to the buttons), this is what I have.
The code to achieve this (which is different than yours), is as follows:
CellMenuView.m
self.backgroundColor = [UIColor blackColor];
_editButton.layer.borderColor = [UIColor whiteColor].CGColor;
_editButton.layer.borderWidth = 2;
_fireButton.layer.borderColor = [UIColor whiteColor].CGColor;
_fireButton.layer.borderWidth = 2;
UITableViewCell subclass
// Change in height to make it taller
_menuView = [[TestBtn alloc] initWithFrame:CGRectMake(0.0f, 20.0f, 320.0f, 60.0f)];
UITableViewController subclass
self.tableView.rowHeight = 100;
After testing, mine works as expected. If I click within the white squares, the button action is performed as normal, and didSelectRowAtIndexPath is not called. didSelectRowAtIndexPath is only called when I click outside of the buttons.
I think the issue here might be your button heights/frames, as well as your row height. Add borders to your buttons, to check its clickable area, and increase the height of the button to increase the clickable area.

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.

How to call PopOver Controller from UITableViewCell.accessoryView?

First I would like to say that I'm really new to ipad/ipod/iphone development, and to objective-c too.
With that being said, I'm trying to develop a small application targeting the iPad, using Xcode and IB, basically, I have a table, for each UITableViewCell in the table, I added to the accessoryView a button that contains an image.
Here is the code:
UIImage *img = [UIImage imageNamed:#"myimage.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, img.size.width, img.size.height);
button.frame = frame; // match the button's size with the image size
[button setBackgroundImage:img forState:UIControlStateNormal];
// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
So far, so good, now the problem is that I want a PopOver control to appear when a user taps the button on the accessoryView of a cell.
I tried this on the "accessoryButtonTappedForRowWithIndexPath" of the tableView:
UITableViewCell *cell = [myTable cellForRowAtIndexPath:indexPath];
UIButton *button = (UIButton *)cell.accessoryView;
//customViewController is the controller of the view that I want to be displayed by the PopOver controller
customViewController = [[CustomViewController alloc]init];
popOverController = [[UIPopoverController alloc]
initWithContentViewController: customViewController];
popOverController.popoverContentSize = CGSizeMake(147, 122);
CGRect rect = button.frame;
[popOverController presentPopoverFromRect:rect inView:cell.accessoryView
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
The problem with this code is that it shows the Popover at the top of the application View, while debugging I saw the values of "rect" and they are:
x = 267
y = 13
so I think it is pretty obvious why the PopOver is being displayed so up on the view, so my question is, how can I get the correct values for the PopOver to appear just below the button on the accessoryView of the cell?
Also, as you can see, I'm telling it to use the "cell.accessoryView" for the "inView:" attribute, is that okay?
Try using button.bounds instead of button.frame since the rect is relative to the inView.
Also note that if the cell is near the bottom of the screen, the popover may not appear at the right size because you are forcing the arrow in the Up direction. You should either handle this manually or just use Any.
[popOverController presentPopoverFromRect:rect inView:cell.accessoryView
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
Changing inView:cell.accessoryView to inView:cell
here's for swift:
let cell = tableView.cellForRowAtIndexPath(indexPath)
let rect = tableView.convertRect(tableView.rectForRowAtIndexPath(indexPath), toView: tableView)
var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("loadZone") as! UIViewController
var nav = UINavigationController(rootViewController: popoverContent)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController
popoverContent.preferredContentSize = CGSizeMake(100,200)
popover!.sourceView = tableView
popover!.sourceRect = rect
self.presentViewController(nav, animated: true, completion: nil)