Since starting with iPhone app development (last 9 months) I have only used IB. I have a project to work on already built by another developer that I need to optimise for iPhone screen. No problem in IB, I know how to do that, in this project however the Nav bar is added using code only and is an image view. Could someone advise me how I go about resizing/positioning the nav bar when IB isnt used? Im trying to enhance this app for the iphone 5 screen.
#define BAR_FRAME CGRectMake(0,0,320.0f,43.0f)
#implementation ICNavbarView
#synthesize homeButton=__homeButton;
#synthesize prevButton=__prevButton;
#synthesize nextButton=__nextButton;
#synthesize delegate=__delegate;
- (id)initWithFrame:(CGRect)frame
{
LogCmd();
self = [super initWithFrame:BAR_FRAME];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.alpha = 0.9f;
// Add Navigation bar background // <<<<<< navigation bar from ui image
UIImageView *bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BgNavBarNew"]];
[self addSubview:bgView];
// Add back button
__prevButton = [UIButton buttonWithType:UIButtonTypeCustom];
__prevButton.frame = CGRectMake(30.0f, 6.0f, 29.0f, 31.0f);
UIImage *prevButtonPressed = [UIImage imageNamed:#"BtnPrevPressed"];
[__prevButton setImage:[UIImage imageNamed:#"BtnPrev"] forState:UIControlStateNormal];
[__prevButton setImage:prevButtonPressed forState:UIControlStateSelected];
[__prevButton setImage:prevButtonPressed forState:UIControlStateHighlighted];
[__prevButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:__prevButton];
// Add next button
__nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
__nextButton.frame = CGRectMake(262.0f, 6.0f, 29.0f, 31.0f);
UIImage *nextButtonPressed = [UIImage imageNamed:#"BtnNextPressed"];
[__nextButton setImage:[UIImage imageNamed:#"BtnNext"] forState:UIControlStateNormal];
[__nextButton setImage:nextButtonPressed forState:UIControlStateSelected];
[__nextButton setImage:nextButtonPressed forState:UIControlStateHighlighted];
[__nextButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:__nextButton];
// Add home button
__homeButton = [UIButton buttonWithType:UIButtonTypeCustom];
__homeButton.frame = CGRectMake(145.0f, 6.0f, 31.0f, 30.0f);
UIImage *homeButtonPressed = [UIImage imageNamed:#"BtnHomePressed"];
[__homeButton setImage:[UIImage imageNamed:#"BtnHome"] forState:UIControlStateNormal];
[__homeButton setImage:homeButtonPressed forState:UIControlStateSelected];
[__homeButton setImage:homeButtonPressed forState:UIControlStateHighlighted];
[__homeButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:__homeButton];
}
return self;
}
- (id)init
{
return [self initWithFrame:CGRectZero];
}
#pragma mark - Button handlers
- (void)buttonPressed:(id)sender
{
if (sender == __prevButton) {
[self.delegate performSelector:#selector(navBarPrevButtonPressed)];
} else if (sender == __homeButton) {
[self.delegate performSelector:#selector(navBarHomeButtonPressed)];
} else {
[self.delegate performSelector:#selector(navBarNextButtonPressed)];
}
}
#end
So far I tried UIViewAutoresizingFlexibleHeight; like this
// Add Navigation bar background
UIImageView *bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BgNavBarNew"]];
[self addSubview:bgView];
//resize
bgView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
This seems to make no difference and the nav bar hasn't moved
I've used this before, but I used the setter function instead of using the property. I don't know if that would change anything or not, but try it this way:
[bgView setAutoresizingMask:(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth)];
The parens are important, if you have multiple re-sizing options.
Related
I downloaded from a free icon DB a thumb up icon, its size is too large for a button and it had white background.I decided to open it in pixelmator resized the icon and removed the background. when opening it with preview it looks great but when its set to be the button's image in xcode it appears as a white circle.
here is the icon after edit (30x30 png)
and this is how it looks on the button
what should I do to fix this?
edit/ upadte:
I tried #yunas code and it works in the navigation bar not for the toolbar (didn't even show the button).
Trying this code:
UIImage* image = [UIImage imageNamed:#"imageName"];
UIBarButtonItem *likeBtn = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:#selector(action_clicked:)];
NSArray* toolbarItems = [NSArray arrayWithObjects:likeBtn,nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
resulted again in a button with the white drawing
So I was wondering: Is it even possible to have colored buttons in the toolbar? maybe i'm trying the imposible...
edit/ upadte II - the solution: wrapping a UIButton inside a UIBarButtonItem
#interface StatusUIBarButtonItem : UIBarButtonItem
- (id) initWithStatus: (enum StatusEnum)p_statusEnum;
#end
#implementation StatusUIBarButtonItem
- (instancetype)initWithStatus:(enum StatusEnum)p_statusEnum
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[self getStatusImage] forState:UIControlStateNormal];
[button addTarget:self action:#selector(status_Clicked:) forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 20, 20)];
self = [super initWithCustomView:button];
if (self)
{
self.statusButton = button;
}
return self;
}
#end
then in the ViewController class:
-(void) viewDidLoad
{
StatusUIBarButtonItem* stausBtn = [[StatusUIBarButtonItem alloc] initWithStatus:self.status];
NSArray* toolbarItems = [NSArray arrayWithObjects: stausBtn, nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
}
I hope this will help others that like me want colored images in the toolbar
UIImage *buttonImage = [UIImage imageNamed:#"imageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
button.adjustsImageWhenDisabled = NO;
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(action:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = customBarItem;
I'm just adding a quick intro screen with a button, which compiles and displays properly, but my button doesn't respond.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad!");
[self showIntro];
}
// make a quick Intro screen
- (void) showIntro {
UIImageView *myBackImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[myBackImage setImage:(UIImage *) [UIImage imageNamed:#"myBkgnd.png"]];
UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom ];
[clickBtn addTarget:self action:#selector(myButton_pressed:) forControlEvents:UIControlEventTouchUpInside];
[clickBtn setImage:(UIImage *) [UIImage imageNamed:#"btnImage.png"] forState:UIControlStateNormal];
clickBtn.frame = CGRectMake(111, 200, 75, 60);
[myBackImage addSubview:clickBtn];
[self.view addSubview:myBackImage];
}
- (void)myButton_pressed:(UIButton*)button {
NSLog(#"Button Pressed!");
}
What am I overlooking?
Thanks!
As you have added UIButton in UIImageView but didn't you forgot imageView's userInteraction by default NO. So :
myBackImage.userInteractionEnabled = YES;
EDIT : Just formatted
I have a iOS5 project using storyboard and with ARC on.
I have a view in storyboard with the class thisViewController and in there I got a smaller subview which I dragged in and gave it the class thisView.
thisView has a custom drawRect function, that works and draws what I want nicely.
But I also want to add buttons dynamically, so I'll add them in the initWithFrame method of thisView like so:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(#"This is called <3");
UIButton *btn= [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 50, 50);
btn.backgroundColor = [UIColor redColor];
[btn setTitle:#"Play" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
[self bringSubviewToFront:btn]; // last thing I tried, didn't work, thought z-index was to low or something
}
return self;
}
The function is being called since the NSLog displays, but the button is nowhere to be found
--EDIT--
Extra information:
ThisView.h
#interface RadarView : UIView <CLLocationManagerDelegate>{
CLLocation *currentLocation;
}
Dont add the SubView in the init method.
Add the SubView in the - (void)layoutSubviews.
- (void)layoutSubviews {
[super layoutSubviews];
if (![self viewWithTag:12345]) {
UIButton *btn= [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 50, 50);
btn.tag = 12345;
btn.backgroundColor = [UIColor redColor];
[btn setTitle:#"Play" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
}
I found what the problem was thanks to some comments and the chat
There was an init in the radarviewcontroller, which triggered initwithframe, which made the NSLog display, and the initwithcoder wasn't used so I didn't see anything, that was the problem and got stuff mixed up. Thanks for commenting and helpin!
I have a view with a generic rounded rect button that segues to another view. When users press the rounded rect it starts a fetch. I would like to have a spinning wheel replace the text ("Next") inside the rounded rect button while the fetch is processed.
I created the spinner:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
But I don't know how to make it replace the text in the rounded rect button.
Any suggestion? Thank you.
Create (or get a reference to) the button as usual, then, while handling the button click, create your spinner and set it as a subview of the button. It's probably also worth disabling the button to stop multiple clicks.
Something along the following lines should do the trick:
...
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10, 10, 70, 40);
[button setTitle:#"Next" forState:UIControlStateNormal];
[button addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
...
- (void)click:(UIButton *)button {
[button setTitle:#"" forState:UIControlStateNormal];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
spinner.frame = button.bounds;
[button addSubview:spinner];
button.enabled = NO;
// do your actual work...
}
I wrote a category that utilizes associated objects
UIButton+ActivityIndicator.h
// Created by reynaldo on 1/16/14.
#import <Foundation/Foundation.h>
#interface UIButton (ActivityIndicator)
- (void)startActivityIndicator;
- (void)stopActivityIndicator;
#end
UIButton+ActivityIndicator.m
// Created by reynaldo on 1/16/14.
#import <objc/runtime.h>
#import "UIButton+ActivityIndicator.h"
static char TITLE_KEY;
static char ACTIVITY_INDICATOR_KEY;
#implementation UIButton (ActivityIndicator)
- (void)startActivityIndicator {
objc_setAssociatedObject(self, &TITLE_KEY, self.currentTitle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self setTitle:#"" forState:UIControlStateNormal];
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[self addSubview:activityIndicatorView];
activityIndicatorView.frame = CGRectMake(self.frame.size.width / 2, self.frame.size.height / 2. - 2, 7, 7);
[activityIndicatorView startAnimating];
objc_setAssociatedObject(self, &ACTIVITY_INDICATOR_KEY, activityIndicatorView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)stopActivityIndicator {
NSString *title = objc_getAssociatedObject(self, &TITLE_KEY);
UIActivityIndicatorView *activityIndicatorView = objc_getAssociatedObject(self, &ACTIVITY_INDICATOR_KEY);
if(activityIndicatorView) {
[activityIndicatorView removeFromSuperview];
}
if(title.length) {
[self setTitle:title forState:UIControlStateNormal];
}
}
#end
How to create a UIButton With two actions.
I know by using UILongPressGestureRecognizer we can perform Longpress.
But my requirement is,When I Long Press UIButton,it has to perform one action and when touch
up inside it, it has to perform another action.
Thanks.
Below is my code.
UIImage *redImage = [UIImage imageNamed:#"TabFav2.png"];
tabRedbutton = [UIButton buttonWithType:UIButtonTypeCustom];
[tabRedbutton setImage:redImage forState:UIControlStateNormal];
tabRedbutton.frame = CGRectMake(0.0, 0.0, 50,35);
redTAb = [[UIBarButtonItem alloc] initWithCustomView:tabRedbutton];
[tabRedbutton addTarget:self action:#selector(redbottonmethod) forControlEvents:UIControlEventTouchUpInside];
longpressGesture1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressHandler:)];
longpressGesture1.minimumPressDuration =0.1;
[longpressGesture1 setDelegate:self];
longpressGesture1.cancelsTouchesInView = NO;
[tabRedbutton addGestureRecognizer:longpressGesture1];
[longpressGesture1 release];
- (void)longPressHandler:(UILongPressGestureRecognizer *)gestureRecognizer {
if (longpressGesture.state == UIGestureRecognizerStateBegan)
{
NSlog(#"Long press");
}
}
-(void)redbottonmethod
{
NSlog(#"single tapped");
}
For the tap you can use UIButton's "addTarget:..." method and for the longpress you can add a gesture recognizer:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(100.0, 100.0, 100.0, 20.0);
[btn setTitle:#"Test" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(userTapped:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] init];
[gr addTarget:self action:#selector(userLongPressed:)];
[btn addGestureRecognizer:gr];
[gr release];
[self.view addSubview:btn];
Of course you need to implement the 2 methods that will be called:
- (void)userTapped:(id)sender {
NSLog(#"user tapped");
}
- (void)userLongPressed:(id)sender {
NSLog(#"user long pressed");
}
Hope that helps.
=========
EDIT: It seems that you are using your button as a BarButtonItem inside a UIToolbar. So I changed my code to do the same:
- (void)viewDidLoad {
[super viewDidLoad];
// set up the button
UIImage *redImage = [UIImage imageNamed:#"TabFav2.png"];
UIButton *tabRedbutton = [UIButton buttonWithType:UIButtonTypeCustom];
tabRedbutton.backgroundColor = [UIColor redColor];
[tabRedbutton setImage:redImage forState:UIControlStateNormal];
tabRedbutton.frame = CGRectMake(0.0, 0.0, 50,35);
// set up a bar button item with the button as its view
UIBarButtonItem *redTab = [[UIBarButtonItem alloc] initWithCustomView:tabRedbutton];
// set up toolbar and add the button as a bar button item
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 100.0, 768.0, 40.0)];
toolbar.barStyle = UIBarStyleBlack;
NSArray *items = [NSArray arrayWithObject:redTab];
[toolbar setItems:items];
[self.view addSubview:toolbar];
[toolbar release];
// add tap handler to button for tap
[tabRedbutton addTarget:self action:#selector(redbottonmethod) forControlEvents:UIControlEventTouchUpInside];
// add gesture recognizer to button for longpress
UILongPressGestureRecognizer *longpressGesture1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressHandler:)];
longpressGesture1.minimumPressDuration =0.1;
[tabRedbutton addGestureRecognizer:longpressGesture1];
[longpressGesture1 release];
}
And the two methods that get called:
- (void)longPressHandler:(UILongPressGestureRecognizer *)gestureRecognizer {
NSLog(#"Long press");
}
-(void)redbottonmethod {
NSLog(#"single tapped");
}
This code definitely works.
By the way: I noticed that in your code in the 2 methods that get called you have typo: You must use NSLog() and not NSlog(). Could that be the problem?