How to set UIBarButtonItem with customView without losing selector - objective-c

I have a UIBarButtonItem in IB
That button has selectors.
Things work fine but I want to change the appearance.
Hence I did:
UIImage * imageSetting= [UIImage imageNamed:#"setting-button"];
UIImageView * imageView = [[UIImageView alloc]initWithImage:imageSetting];
self.editSettings = [self.editSettings initWithCustomView:imageView];
Now appearance works fine but pressing the button won't get me to any code at all.
What to do?

Replace
self.editSettings = [self.editSettings initWithCustomView:imageView];
with
[self.editSettings setCustomView:imageView];
Hope this helps you..

After you instantiate your custom item, you need to set a target and an action on it.
e.g.
if(self.editSettings) // make sure it exists
{
self.editSettings.target = self;
self.editSettings.action = #selector(doSomething:)
}
(assuming you have a method named "doSomething:" in your view controller...

You can have a create action method for that bar button item and then connect that action in xib you can do this programmatically also using below code:
self.navigationController.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonItemStylePlain target:self action:#selector(addtechniciansnametoplist:)];

Related

Can't hide back button inside my navigationbar

I am trying to hide my backbutton in the firstView after I logged into the application. I have this piece of code inside my ViewWillAppear.
self.navigationController.navigationItem.hidesBackButton = YES;
self.navigationController.navigationBar.hidden = NO;
But my back button will not dissapear.
any help ?
Kind regards.
use this instead
self.navigationItem.hidesBackButton = YES;
Try these couple of lines , this will work out:
self.navigationItem.hidesBackButton = TRUE;
self.navigationItem.leftBarButtonItem = nil;
You can set a custom UIBarButtonItem as left bar button. That one you can try to hide or desing in a smooth way that it helps achieving what you want to do.
If you want to hide back button, than maybe you do not want to get back to previous screen. If this is the case, instead of pushing navigation controller show your view modally.
Otherwise do the following:
UIButton* myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
UIBarButtonItem* myBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];
myButton.hidden = YES;

UIButton inside UIView doesn't respond to touch events

I've put a UIButton inside a custom UIView and the button is not receiving any touch events (it doesn't get into the highlighted state, so my problem is not about being unable to wire up a touch inside up handler). I've tried both putting it into the XIB in Interface Builder, and also tried programatically adding the UIButton into the UIView seperately, both ended with no luck. All my views are inside a UIScrollView, so I first though UIScrollView may be blocking them, so I've also added a button programatically exactly the same way I add my custom view into UIScrollView, and the button worked, elimination the possibility of UIScrollView could be the cause. My View's hiearchy is like this:
The button is over the image view, and the front layer isn't occupying my button completely, so there's no reason for me not be physically interacting with the button. At my custom view's code side, I'm creating my view as such:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIView *sub = [[[NSBundle mainBundle] loadNibNamed:#"ProfileView" owner:self options:nil] objectAtIndex:0];
[self addSubview:sub];
[sub setUserInteractionEnabled:YES];
[self setUserInteractionEnabled:YES];
CALayer *layer = sub.layer;
layer.masksToBounds = YES;
layer.borderWidth = 5.0;
layer.borderColor = [UIColor whiteColor].CGColor;
layer.cornerRadius = 30.0;
/*layer.shadowOffset = CGSizeZero;
layer.shadowRadius = 20.0;
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowOpacity = 0.8;
*/
}
return self;
}
I've tried all combinations of setUserInteractionsEnabled, and had no luck. (Yes, also set them to checked in Interface Builder too). I've also read in another question with a similar problem that I should try overriding 'canBecomeFirstResponder' to return 'YES' and I've also done that too. But the problem persists, I can't click the button. I've not given any special properties, settings to the button, it's just a regular one. My other objects in the view (labels below, image view behind the button etc.) are working properly without problems. What could be possibly wrong here?
Thanks,
Can.
UPDATE: Here is a quick reproduction of the problem: https://dl.dropbox.com/u/79632924/Test.zip
Try to run and click the button.
Looking at the test project, I believe your problem in the way you create TestView, you do not specify the frame for it, so basically the parent view is 0 size, and the subviews you see from XIB extending out of the parent view and thus do not get anything in responder chain.
You should either specify the frame when creating TestView, or adjust the frame after loading XIB file.
I have had this problem as well. The cause for me was that the UIButton superview frame was of height 0, so I believe that even though a touch was happening, it was not being passed down to the button.
After making sure that the button's superview took a larger rectangle as a frame the button actions worked.
The root cause for this problem on my side was a faulty auto layout implementation (I forgot to set the height constraint for the button's superview).
I've found the solution. I was initializing my custom view as:
MyView *view = [[MyView alloc] init];
I've initialized it instead with a frame of my view's size, and it started responding to events:
CGRect rect = CGRectMake(0,0,width,height);
MyView *view = [[MyView alloc] initWithFrame:rect];
Storyboard Solution
Just for anyone wanting a solution to this when using storyboards and constraints.
Add a constraint between the superview (containing the button) and the UIButton with an equal heights constraint.
In my case, I had selected embed UIButton in a UIView with no inset on the storyboard. Adding the additional height constraint between the UIButton and the superview allowed the UIButton to respond to touches.
You can confirm the issue by starting the View Debugger and visually confirm that the superview of the UIButton is not selectable.
(Xcode 11, *- Should also work in earlier versions)

Can I add an action to a NSImage which is drawn in a NSTextFieldCell?

Can I add an action to a NSImage which is drawn in a NSTextFieldCell ?
Or should I implement a NSImageView or NSButton for it ? If so, how do I add such view or button to the NSTextFieldCell ?
thanks
Instead of using NSImage,you can use NSButton .Set its image as you are doing for NSImage.Add the selector for that button .
NSButton *objNSButton = [[NSButton alloc] init];
[objNSButton setImage: YourImage];
[objNSButton setTarget:self];
[objNSButton setAction:#selector(buttonAction:)];
[objNSButton drawWithFrame:'SelfDefinedRectForButton' inView:NStextFieldCellObject];
You can also setAlternate image option if you want chagne in image on click of that button.
create a custom Button with UIButtonTypeCustom and then set image by using -setImage function and then add a selector as a target.
You can also refer this

How set set title to leftBarButtonItem

I have root ViewController and detailed ViewController. When i push to detailedViewController i get leftBarButtonItem with the title from the root one. But i want the title to be just "Back", nothing more. So how to do that?
This doesn't help
self.navigationItem.leftBarButtonItem.title = #"Back";
To create my on type barButtonItem(for example 104 with left arrow) and to set it to leftBarButtonItem is terrible decision.
Is there other way than to change the title of the rootViewController manually before pushing?
From Apple's doc:
backBarButtonItem
The bar button item to use when a back button is needed on the
navigation bar.
#property(nonatomic, retain) UIBarButtonItem *backBarButtonItem
Discussion
When this navigation item is immediately below the top item in the
stack, the navigation controller derives the back button for the
navigation bar from this navigation item. When this property is nil,
the navigation item uses the value in its title property to create an
appropriate back button. If you want to specify a custom image or
title for the back button, you can assign a custom bar button item
(with your custom title or image) to this property instead. When
configuring your bar button item, do not assign a custom view to it;
the navigation item ignores custom views in the back bar button
anyway.
So, you can create create your barButtonItem (e.g. – initWithTitle:style:target:action:) and assign it to that property.
In addition, if you want to have a custom image for UIBarButtonItem (left or right) I suggest you to create a category extension like the following:
//UIBarButtonItem+Extension.h
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action;
//UIBarButtonItem+Extension.m
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button setTitle:title forState:UIControlStateNormal];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return [barButtonItem autorelease];
}
and then use it as
UIBarButtonItem* backBarButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:#"YoutImageName"] title:#"YourTitle" target:self action:#selector(doSomething:)];
I finally figured out all the wrinkles in this today, and it's simpler then above.
The child's back button text is based on values set in its parent. This is obvious behaviour, when you think about it: If a view controller can be reached from two parents, the back button's text should depend on which pushed it.
If the text is always the same:
Select the parent view controller's Navigation Item in the editor.
Put the text into the Back Button value.
And like that you're done. When this view controller is pushed aside by a new view controller, that new view controller will get this text as its title.
If the text is dynamic:
Select the parent view controller's Navigation Item in the editor.
Put some text into the Back Button value.
Set the title when it should change in the parent view controller: self.navigationItem.backBarButtonItem.title = dynamicText;
And, again, you're done.
To be clear, you can set this at any time in the parent view controller. It will only be shown when another view controller is pushed.
If you don't put the text in the Back Button in the designer, the process of instantiating the view controller won't create self.navigationItem.backBarButtonItem, and you can't set the title of a nil object. I believe this is where all of the confusion around this stems from.
Of course, you can create this at runtime, but if you're already doing most of your work in the storyboard/nib it's easier to let the decoder do it for you.
If you're more curious about this, I just wrote a blog post on the subject as well. It has some more details.
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] init];
backButtonItem.title = NSLocalizedString(#"Back", nil);
self.navigationItem.backBarButtonItem = backButtonItem;
It works for me:
[self.navigationItem.leftBarButtonItem setTitle:#"Back"];
(back arrow image and custom text)

Set title/icon etc to TabBarItem created in IB, through code?

I have a TabBar that I've created through IB, I chose "create new project" -> "Tab bar application". Is there a way for me to access one of the TabBarItems for customization through the code?
It seems to me that something like:
[[self.tabBarController.tabBar.items objectAtIndex:0] setTitle:#"Button one"];
should set the title of that item to "Button one", but it doesen't. The title itself is not a problem (I can set that through IB aswell), however adding an Icon seems to be.
So to sum up, what I really want to know is: Is there a way to add an Icon to a TabBarItem created through IB?
SOLUTION:
Adding in viewDidLoad in the first view, being loaded automatically upon starting the app:
UITabBarController *tb = [self tabBarController];
[[tb.tabBar.items objectAtIndex:1] setTitle:#"Title"];
Let me set the title of the second button (objectAtIndex: 1). I was also able to set the image the same way, which also worked for buttons one (objectAtIndex: 0) and three (objectAtIndex: 2).
Add this to your viewDidLoad: method of one of the tabBar viewControllers and it should work:
- (void)viewDidLoad
{
[super viewDidLoad];
//Get the tabBarItem
UITabBarItem *tbi = [self tabBarItem];
//Give it a lable
[tbi setTitle:#"Title A"];
//create a image from a file for the tabBar
UIImage *i = [UIImage imageNamed:#"NiceImage.png"];
//and put it on the tabBar
[tbi setImage:i];
}
You should be able to set the image and title properties on the TabBarItems:
UITabBarItem *item = (UITabBarItem *)[tabBarController.tabBar.items objectAtIndex:0];
item.image = [UIImage imageNamed:#"home.png"];
Don't forget that the UITabBar only uses the alpha values out of the image you set, so if you don't have an alpha channel in the image you may not see anything when you set an image on the tab bar item.
I've never created a tab bar through IB (always through code), however to set title and icon I use
controller.title = #"Controller";
controller.tabBarItem.image = [UIImage imageNamed:#"image.png"];
where controller is the UIViewController added to the viewControllers' array of the UITabBarController.