How can I add padding to the UIlabel text that created programmatically?
NSArray *collectionViewArrayTitle = _titleArray[collectionView.index];
NSString *title= collectionViewArrayTitle[indexPath.item];
newslabel =[[UILabel alloc] initWithFrame:CGRectMake(0, 80, 130, 50)];
_newslabel.textColor=[UIColor whiteColor];
_newslabel.backgroundColor=[UIColor blackColor] ;
_newslabel.alpha=1.0f;
_newslabel.text=title;
_newslabel.tag=collectionView.index;
_newslabel.lineBreakMode=NSLineBreakByTruncatingTail;
_newslabel.numberOfLines=4;
The best way to add 'padding' to your labels is to make a subclass of UILabel and add the edgeInsets property.
CustomLabel.h
#import <UIKit/UIKit.h>
#interface CustomLabel : UILabel
#property (nonatomic, assign) UIEdgeInsets edgeInsets;
#end
CustomLabel.m
#import "CustomLabel.h"
#implementation CustomLabel
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.edgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); //customize padding here
}
return self;
}
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}
#end
Another way of adding padding is to use a second layer. This may be a lot easier to accomplish but is imo not the most clean way to deal with it. You can add a UIView with the size of the label and then adjust that frame with some padding. Then you can add the intended UILabel to this view and play with the origins to get the right padding this way.
NSLayoutConstrains are Obj-C objects. You can also create them programatically. Or you can also create them in the Storyboard and drag an outlet to your controller and manipulate them on code.
On code you can handle that with the NSConstrain class or you can use the VFL (visual format language). In any case, check Apple's documentation for it. Once you get the handle of it, it's quite straightforward.
Related
I am trying to get started with UI programming in iOS, my first mobile application I mainly used story boards so going forward I would like my UI's to be more flexible. I have followed a couple tutorials online, word for word and line by line, I still can not get my views and subviews to show up when running the Xcode Simulator. I created a Single View Application with one viewController. Here is my code in my "ViewController.h" and "ViewController.m" file. What am I doing wrong here folks? My simulator is not displaying anything and according to the tutorials I have been following it should be.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property(strong, nonatomic) UILabel *label1;
#property(strong, nonatomic) UIButton *someButton;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Create the label
self.label1 = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 25)];
self.label1.text = #"I am a label";
// Create the button
self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.someButton.frame = CGRectMake(10, 50, 100, 37);
[self.someButton setTitle:#"Example Button" forState:UIControlStateNormal];
// Add them to the main view
[self.view addSubview:self.label1];
[self.view addSubview:self.someButton];
}
#end
Create a new project without the storyboard and put following code, it will work..
UILabel *testLabel;
testLabel=[[UILabel alloc]init];
testLabel.text=#"Hello World!";
testLabel.frame = CGRectMake(10, 50, 100, 37);
[self.view addSubview:testLabel];
Well your code is working fine in my xcode i created new single view based application and deleted the storyboard and copy pasted your code
When you programmatically create a UIView, UIButton or UILable, there aren't any layout constraints defined. You have to add them manually. If you do have some layoutconstraints configured for a certain view, they can be removed like so:
[view removeConstraints:view.constraints]
Make sure you are showing the ViewController first.
I want to make an Advertising banner in my app. A bit like iAd's.
I was going to make it by having a UIImage on the view then assigning the banner image. I would then add a touch gesture so the user could click it and go to another view in my app. I Know That I can do this on one view quite easily but I want this to be on most views in the app. Whats the best way for adding the banner to more than one view with out writing the same code more that once?
The below design shows the sort of banner im after.
Thanks
#import <UIKit/UIKit.h>
#class custom;
#protocol adDelegate
- (void)viewAd:(NSString *)adRate;
#end
#interface custom : UIView
#property (strong, nonatomic) UIImage *viewImage;
#property (assign) id <adDelegate> delegate;
#end
// Main class
#import "custom.h"
#implementation custom
#synthesize viewImage;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = viewImage;
[self addSubview:imageView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.delegate viewAd:#"view"];
}
You can Create a UIView Class and call it BannerView for instance.
// in the bannerView.h
#import <UIKit/UIKit.h>
#interface BannerView : UIView{
UIImageView* bannerImage;
}
#property(nonatomic,retain) UIImageView* bannerImage;
#end
//in the bannerView.m
#import "BannerView.h"
#implementation BannerView
#synthesize bannerImage;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
bannerImage=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"banner-image.png"]];
bannerImage.frame=CGRectMake(0, 0, 320, 100);
[self addSubview:bannerImage];
// add a uibutton on top of the uiimageview and assign an action for it
// better than creating an action recogniser
UIButton* actionButton=[UIButton buttonWithType:UIButtonTypeCustom];
actionButton.frame=CGRectMake(0, 0, 320, 100);
[actionButton addTarget:self action:#selector(yourAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:actionButton];
}
-(void) yourAction{
// do what ever here like going to an other uiviewController as you mentionned
}
#end
Now you can call this view from any View Controller this way
BannerView* banner=[[BannerView alloc] initWithFrame:CGRectMake(0, 300, 320, 100)];
[self.view addSubview:banner];
Try creating a parent class from UIView where you do all the display and handling of the banner using your UIImageView and gesture recognizers. Then whichever views need this functionality, derive them from this parent class, and override default handling in method so that you can customize the behavior in your child class.
A few suggestions:
First, why not just use a UIButton instead of a UIImage with a Gesture? All you're really doing is replicating button functionality after all...
Second, I'd probably tackle the overall problem by creating a class that includes the UIButton, like so:
#interface YourSuperViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIButton *adButton;
- (IBAction)adTouched:(id)sender;
#end
In the viewDidLoad for this class, create the button, and add it to the view, and add your ad-specific logic to the adTouched action.
Then create the rest of the views in your app as an instance of YourSuperViewController. Like so:
#interface SomeOtherViewController : YourSuperViewController
Now the SomeOtherViewController will auto-magically have the ad button and respond to a touch on it properly. Done!
What everyone else has said is the best way. If you need custom functionality, subclassing is probably the way to go.
I just wanted to add one pedantic thing. Its important to remember that a UIImage is not a view. There has never been a UIImage on the screen, ever. A UIImage is a model object. It is just a collection of data. A UIImageView is a view object and as such, a UIImageView can display itself on the screen.
This might seem overly pedantic and nitpicky, but its important to have these things sorted out in our heads in order to effectively use MVC (model, view, controller)
I have a UITableView and i want to right a text in a row which should be right aligned and another text which should be left aligned. And both of those texts should start with some space from border of the row. I don't want them to start with the border of the row. How can i do that?
I want to write text in every row which is left aligned and also a text which is right alighned.
Thanks in advance.
In your cellForRowAtIndexPath method just create a cell with 2 UILabels and give them the desired location. Small example:
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 50, 20)];
UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(80, 10, 50, 20)];
label1.textAlignment = UITextAlignmentLeft;
label2.textAlignment = UITextAlignmentRight;
//other labels customization and add them to your cell
return cell;
}
did it without SDK nearby, so there might be some mistakes.
Hope it helps
UILabel is very limited in terms of styling and layout. Considering either using multiple layouts or CoreText.
what you could do is subclass the label and over write its drawtextinrect function like so
#interface UILabelCustom : UILabel
- (void)drawTextInRect:(CGRect)rect;
#end
#implementation UILabelCustom
-(void)drawTextInRect:(CGRect)rect{
UIEdgeInsets insets = {5, 5, 5, 5};
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
#end
this would allow you to give a margin around the edges of the label
also you could create a uiview that contains 2 of this custom labels and left and right align them accordingly. using the uvview as a container for the 2 labels to position them as needed. i reckon that could create the effect you looking for
edit: just seen your edit was for table cell. you would need to create a custom cell as well as custom uilabel
#interface CustomCell : UITableViewCell {
}
#property (retain, nonatomic) UILabelCustom *label1,*label2;
#end
#implementation CustomCell
#synthesize label1, label2;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)dealloc
{
[label1 release];
[label2 release];
[super dealloc];
}
#end
In order to create an absolute bottomed footer on top of a tableView I found that using UIToolbar for this and adding custom views for it worked fine.
My problem is that I already use this as a toolbar for a webview, and here with another background image than I need now.
By replacing the drawRect function in UIToolbar+addition.m I have a global toolbar for this that works fine in my webviews.
How can I expand this so that I can select which version(background) to use the different places?
My UIToolbar+addition.m:
#import "UINavigationBar+addition.h"
#implementation UIToolbar (Addition)
- (void) drawRect:(CGRect)rect {
UIImage *barImage = [UIImage imageNamed:#"toolbar-bg.png"];
[barImage drawInRect:rect];
}
#end
Try creating separate .h and .m files for each "version", and import the appropriate .h into the class file you'd like it to affect.
Why not just add a barImage property to your extension?
#interface UIToolbar (Addition)
#property (nonatomic, retain) UIImage *barImage;
#end
Then, in your implementation (I'm doing this assuming you're not using ARC. If you are, obviously remove the retain/release stuff):
#implementation UIToolbar (Addition)
#synthesize barImage = _barImage;
//Override barImage setter to force redraw if property set after already added to superView...
- (void)setBarImage:(UIImage *)barImage {
if (_barImage != barImage) {
UIImage *oldBarImage = [_barImage retain];
_barImage = [barImage retain];
[oldBarImage release];
//Let this UIToolbar instance know it needs to be redrawn in case you set/change the barImage property after already added to a superView...
[self setNeedsDisplay];
}
}
- (void) drawRect:(CGRect)rect {
[self.barImage drawInRect:rect];
}
//If you're not using ARC...
- (void)dealloc {
[barImage release];
[super dealloc];
}
#end
Now, all you have to do is set the barImage property after instantiating your UIToobar. e.g.:
UIToolBar *myToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; //Or whatever frame you want...
myToolbar.barImage = [UIImage imageNamed:#"toolbar-bg.png"];
[self.view addSubView:myToolbar];
[myToolbar release];
And, if you want to change it after it's already onscreen, you can do so by just setting the barImage property to a new UIImage.
Looks like it's been a year since this question was posted, but hopefully this might help someone.
I'm re-factoring my code and would like to move a whole bunch of UILabels into another class to tidy things up a bit. I'm missing one puzzle piece to be able to do so though (or maybe I'm just tired lol) Anyway here's the simplified code showing my issue. Thanks in advance to anyone who helps :)
#interface MyClass : UIView {
UILabel *classLabel;
}
#property (assign) UILabel *classLabel;
#end
#implementation MyClass
#synthesize classLabel;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)dealloc {[super dealloc];}
#end
#interface LabelTestViewController : UIViewController {
MyClass *myClassInstance;
UILabel *myLabel;
}
#property (assign) UILabel *myLabel;
#end
#implementation LabelTestViewController
#synthesize myLabel;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// this shows a label on the screen as expected
myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 20)];
myLabel.text = #"Hello";
[self.view addSubview:myLabel];
[myLabel release];
// this doesn't show anything on the scree
myClassInstance = [MyClass new];
[myClassInstance drawRect:CGRectMake(10, 50, 50, 20)]; // I suspect I need to call a different method, just don't know which one. initWithFrame is what I used at the time of creation of the label in the previous working scenario. is there an equivalent?
myClassInstance.classLabel.text = #"Goodbye";
[self.view addSubview:myClassInstance.classLabel];
}
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}
- (void)viewDidUnload {}
- (void)dealloc {[super dealloc];}
#end
A couple of things:
1) You should never call drawRect directly. Instead, call setNeedsDisplay or setNeedsDisplayInRect. See the Cocoa Drawing Guide or the UIView Class Reference for more info.
2) But that may not be source of your problem. From your code, it is difficult to tell what ends up in classLabel after you are done setting it up, but I expect it's not what you need. In particular, it needs a frame. I would suggest setting a CGRect variable to myClassLabel.frame and seeing what you end up with.