Related
As we know, the table view separator is so thin and beautiful. Sometimes we have to build some separator line in storyboard or nib, the min number is 1, but actually the line appears much thicker than we expected.
My question is how to draw a 1px line in storyboard?
Xcode 9 Swift: You can add a thin seperator with 1px line in the Storyboard using UIView.
Under Size Inspector, Just set the height to 1, width example to 360.
Apple documentation on UIView.
I got your point too, finally I find way out.
As we know, if we draw a line and set the height by code, we can set the height equal to (1.0 / [UIScreen mainScreen].scale).
But here, you wanna to draw in storyboard.
My way is subclass UIView or UIImageView, based on your demand as OnePXLine. In OnePXLine class, override layoutSubviews like below:
- (void)layoutSubviews {
[super layoutSubviews];
CGRect rect = self.frame;
rect.size.height = (1 / [UIScreen mainScreen].scale);
self.frame = rect;
}
And you can draw 1 px line in storyboard by use this class.
Goodluck!
This would help you if you're coding in Swift:
func lineDraw(viewLi:UIView)
{
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor(red: 197/255, green: 197/255, blue: 197/255, alpha: 1.0).CGColor
border.frame = CGRect(x: 0, y: viewLi.frame.size.height - width, width: viewLi.frame.size.width, height: viewLi.frame.size.height)
border.borderWidth = width
viewLi.layer.addSublayer(border)
viewLi.layer.masksToBounds = true
}
You can do like in any UIControl/UIElement for this and change the height as 1
If you want to 1 Point use this - 1
If you want to 1pixel Use this - 1.0 / UIScreen.mainScreen().scale
Objective-C
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 1)]; // customize the frame what u need
[lineView setBackgroundColor:[UIColor yellowColor]]; //customize the color
[self.view addSubview:lineView];
Swift
var lineView = UIView(frame: CGRect(x: 0, y: 50, width: self.view.frame.size.width, height: 1))
lineView.backgroundColor = UIColor.yellow
self.view.addSubview(lineView)
If you want a more information see this once
you can assign float value for view frame . so what you can do is take any view (lable,textview,view,textfield) and assign height as 0.4f or something programatically and width to match self width.
lable.frame = CGRectMake(0,0,width of self.view,0.4f);
Try it in cellForRowAtIndex
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 1)];
separatorLineView.backgroundColor = [UIColor colorWithRed:242/255.0f green:222/255.0f blue:52/255.0f alpha:1.0];
[cell.contentView addSubview:separatorLineView];
Swift 5 code base on what #childrenOurFuture answered:
class OnePXLine: UIView {
override func layoutSubviews() {
super.layoutSubviews()
var rect = self.frame;
rect.size.height = (1 / UIScreen.main.scale);
self.frame = rect;
}
}
I just placed one search bar controller with table view. Now its look like normal search bar like this :
But i need to change this search bar to some thing like below image. :
Like rounded and search icon should show in last and when i press search, the cancel button should automatically should show.
Now by using code , is it possible to do these changes. Please help me out. How to get like above image.
I am using swift 2.0
Take UIView as containerView for your textField, set its background color as you want.
Set corner radius to the textField and add some padding to it.
Corner radius:
Swift:
let textFieldSearchBar = UITextField()
textFieldSearchBar.layer.masksToBounds = true
textFieldSearchBar.layer.cornerRadius = 5.2
textFieldSearchBar.layer.borderColor = UIColor.lightGrayColor().CGColor
textFieldSearchBar.layer.borderWidth = 1.5
Objective-c:
textFieldSearchBar.layer.cornerRadius = 5.2f;
textFieldSearchBar.layer.borderColor = kTextFieldBorderColor.CGColor;
textFieldSearchBar.layer.borderWidth = 1.5f;
Left padding:
Swift:
let leftPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: paddingWidth, height: 20))
textFieldSearchBar.leftView = leftPaddingView
textFieldSearchBar.leftViewMode = UITextFieldViewMode.Always;
Objective-c:
UIView *leftPaddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingWidth, 20)];
textFieldSearchBar.leftView = leftPaddingView;
textFieldSearchBar.leftViewMode = UITextFieldViewModeAlways;
Right padding:
Swift:
let rightPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: paddingWidth, height: 20))
textFieldSearchBar.rightView = rightPaddingView
textFieldSearchBar.rightViewMode = UITextFieldViewMode.Always;
Objective-c:
UIView *rightPaddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)];
textFieldSearchBar.rightView = rightPaddingView;
textFieldSearchBar.rightViewMode = UITextFieldViewModeAlways;
Now you will need two images, one for Magnifying glass and other for Dismiss/Cross button. Take one button and set these images as background for state Default and Selected.
Make outlet of the button and now when you want to show Magnifying glass do [buttonSearch setSelected: NO]; and when Cross button do [buttonSearch setSelected: YES];
Swift:
buttonSearch.setBackgroundImage(UIImage(named: "magnifyingGlass"), forState: UIControlState.Normal)
buttonSearch.setBackgroundImage(UIImage(named: "crossButton"), forState: UIControlState.Selected)
//Show magnifying glass image
buttonSearch.selected = false
//Show cross button image
buttonSearch.selected = true
I had created custom search bas as below:
Hope this will help you.
I am having a problem with my UITableViewCell's appearance on the iPad. This problem arose sometime between iOS 7 and now, but I don't know for sure when it started. On an iPod or iPhone my cells look fine (portrait or landscape), but on the iPad, the disclosure accessory is very wide. You can see an example in the image below. The tablecell has a green border and the contentview has a brown border. The content view is much smaller than it should be. Table cells without the disclosure accessory look fine.
I am using Xamarin, and I am creating this UI completely in code. Here is the code (I have omitted the code that lays out the inside of the cells ContentView since it isn't relevant:
protected void Draw()
{
Accessory = UITableViewCellAccessory.DisclosureIndicator;
Layer.BorderColor = UIColor.Green.CGColor;
Layer.BorderWidth = 1f;
Frame = new CGRect(0, 0, 320, 42);
ContentMode = UIViewContentMode.ScaleToFill;
AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth;
ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
ContentView.MultipleTouchEnabled = true;
ContentView.ContentMode = UIViewContentMode.Center;
ContentView.ClipsToBounds = true;
ContentView.Layer.BorderColor = UIColor.Brown.CGColor;
ContentView.Layer.BorderWidth = 1f;
}
I tried changing the size of the ContentView by overriding the cell's LayoutSubviews method. However, the ContentView was now as wide as the table, but the disclosure accessory didn't change and was now below the ContentView.
public override void LayoutSubviews()
{
base.LayoutSubviews();
//ContentView.Frame = new CGRect(0, 0, Frame.Size.Width, ContentView.Frame.Size.Height);
}
Again, this isn't a problem at all on the iPhone or iPod. I don't understand what I should be doing different for the iPad to work properly.
Thanks.
Zach Green
Edit - 10/21/2015 11:00
For the moment, I have made a very hacky change that is fixing the issue for me, but I know that future iOS updates will probably break this, so I would prefer a more iOS approved way to do this.
public override void LayoutSubviews()
{
base.LayoutSubviews();
//!! - Hack for ipad layout issue with disclosure indicator
if (Accessory == UITableViewCellAccessory.DisclosureIndicator && UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
ContentView.Frame = new CGRect(0, 0, Frame.Size.Width - 32, ContentView.Frame.Size.Height);
foreach (var view in Subviews.OfType<UIButton>())
{
view.Frame = new CGRect(Frame.Size.Width - 24, view.Frame.Y, 8, view.Frame.Height);
}
}
}
This is due to Apples new readable content margins in iOS9 intended to make content more readable in wider views (iPad Pro).
You can turn this feature off by setting
tableView.cellLayoutMarginsFollowReadableWidth = false
in viewDidLoad
Try this code:
protected void Draw()
{
Accessory = UITableViewCellAccessory.DisclosureIndicator;
Layer.BorderColor = UIColor.Green.CGColor;
Layer.BorderWidth = 1f;
Frame = new CGRect(0, 0, [UIApplication sharedApplication].keywindow.frame.size.width, 42);
ContentMode = UIViewContentMode.ScaleToFill;
AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth;
ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
ContentView.MultipleTouchEnabled = true;
ContentView.ContentMode = UIViewContentMode.Center;
ContentView.ClipsToBounds = true;
ContentView.Layer.BorderColor = UIColor.Brown.CGColor;
ContentView.Layer.BorderWidth = 1f;
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
//!! - Hack for ipad layout issue with disclosure indicator
if (Accessory == UITableViewCellAccessory.DisclosureIndicator && UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
ContentView.Frame = new CGRect(0, 0, [UIApplication sharedApplication].keywindow.frame.size.width - 32, ContentView.Frame.Size.Height);
foreach (var view in Subviews.OfType<UIButton>())
{
view.Frame = new CGRect([UIApplication sharedApplication].keywindow.frame.size.width - 24, view.Frame.Y, 8, view.Frame.Height);
}
}
}
Use the width same as that of [UIApplication sharedApplication].keyWindow.frame.size.width rather than hardcoding the values.
Is there a way to have multiple lines of text in UILabel like in the UITextView or should I use the second one instead?
Set the line break mode to word-wrapping and the number of lines to 0:
// Swift
textLabel.lineBreakMode = .byWordWrapping
textLabel.numberOfLines = 0
// Objective-C
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
// C# (Xamarin.iOS)
textLabel.LineBreakMode = UILineBreakMode.WordWrap;
textLabel.Lines = 0;
Restored old answer (for reference and devs willing to support iOS below 6.0):
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;
On the side: both enum values yield to 0 anyway.
In IB, set number of lines to 0 (allows unlimited lines)
When typing within the text field using IB, use "alt-return" to insert a return and go to the next line (or you can copy in text already separated out by lines).
The best solution I have found (to an otherwise frustrating problem that should have been solved in the framework) is similar to vaychick's.
Just set number of lines to 0 in either IB or code
myLabel.numberOfLines = 0;
This will display the lines needed but will reposition the label so its centered horizontally (so that a 1 line and 3 line label are aligned in their horizontal position). To fix that add:
CGRect currentFrame = myLabel.frame;
CGSize max = CGSizeMake(myLabel.frame.size.width, 500);
CGSize expected = [myString sizeWithFont:myLabel.font constrainedToSize:max lineBreakMode:myLabel.lineBreakMode];
currentFrame.size.height = expected.height;
myLabel.frame = currentFrame;
Use this to have multiple lines of text in UILabel:
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
Swift:
textLabel.lineBreakMode = .byWordWrapping
textLabel.numberOfLines = 0
myUILabel.numberOfLines = 0;
myUILabel.text = #"your long string here";
[myUILabel sizeToFit];
If you have to use the:
myLabel.numberOfLines = 0;
property you can also use a standard line break ("\n"), in code, to force a new line.
You can use \r to go to next line while filling up the UILabel using NSString.
UILabel * label;
label.text = [NSString stringWithFormat:#"%# \r %#",#"first line",#"seconcd line"];
lets try this
textLabel.lineBreakMode = NSLineBreakModeWordWrap; // UILineBreakModeWordWrap deprecated
textLabel.numberOfLines = 0;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;
The solution above does't work in my case. I'm doing like this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
CGSize size = [str sizeWithFont:[UIFont fontWithName:#"Georgia-Bold" size:18.0] constrainedToSize:CGSizeMake(240.0, 480.0) lineBreakMode:UILineBreakModeWordWrap];
return size.height + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// ...
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Georgia-Bold" size:18.0];
}
// ...
UILabel *textLabel = [cell textLabel];
CGSize size = [text sizeWithFont:[UIFont fontWithName:#"Georgia-Bold" size:18.0]
constrainedToSize:CGSizeMake(240.0, 480.0)
lineBreakMode:UILineBreakModeWordWrap];
cell.textLabel.frame = CGRectMake(0, 0, size.width + 20, size.height + 20);
//...
}
Swift 3
Set number of lines zero for dynamic text information, it will be useful for varying text.
var label = UILabel()
let stringValue = "A label\nwith\nmultiline text."
label.text = stringValue
label.numberOfLines = 0
label.lineBreakMode = .byTruncatingTail // or .byWrappingWord
label.minimumScaleFactor = 0.8 . // It is not required but nice to have a minimum scale factor to fit text into label frame
Use story borad : select the label to set number of lines to zero......Or Refer this
Try using this:
lblName.numberOfLines = 0;
[lblName sizeToFit];
UILabel *helpLabel = [[UILabel alloc] init];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:label];
helpLabel.attributedText = attrString;
// helpLabel.text = label;
helpLabel.textAlignment = NSTextAlignmentCenter;
helpLabel.lineBreakMode = NSLineBreakByWordWrapping;
helpLabel.numberOfLines = 0;
For some reasons its not working for me in iOS 6 not sure why. Tried it with and without attributed text. Any suggestions.
Method 1:
extension UILabel {//Write this extension after close brackets of your class
func lblFunction() {
numberOfLines = 0
lineBreakMode = .byWordWrapping//If you want word wraping
//OR
lineBreakMode = .byCharWrapping//If you want character wraping
}
}
Now call simply like this
myLbl.lblFunction()//Replace your label name
EX:
Import UIKit
class MyClassName: UIViewController {//For example this is your class.
override func viewDidLoad() {
super.viewDidLoad()
myLbl.lblFunction()//Replace your label name
}
}//After close of your class write this extension.
extension UILabel {//Write this extension after close brackets of your class
func lblFunction() {
numberOfLines = 0
lineBreakMode = .byWordWrapping//If you want word wraping
//OR
lineBreakMode = .byCharWrapping//If you want character wraping
}
}
Method 2:
Programmatically
yourLabel.numberOfLines = 0
yourLabel.lineBreakMode = .byWordWrapping//If you want word wraping
//OR
yourLabel.lineBreakMode = .byCharWrapping//If you want character wraping
Method 3:
Through Story board
To display multiple lines set 0(Zero), this will display more than one line in your label.
If you want to display n lines, set n.
See below screen.
If you want to set minimum font size for label Click Autoshrink and Select Minimum Font Size option
See below screens
Here set minimum font size
EX: 9 (In this image)
If your label get more text at that time your label text will be shrink upto 9
These things helped me
Change these properties of UILabel
label.numberOfLines = 0;
label.adjustsFontSizeToFitWidth = NO;
label.lineBreakMode = NSLineBreakByWordWrapping;
And while giving input String use \n to display different words in different lines.
Example :
NSString *message = #"This \n is \n a demo \n message for \n stackoverflow" ;
Swift 4:
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.preferredMaxLayoutWidth = superview.bounds.size.width - 10
UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
[labelName sizeToFit];
labelName.numberOfLines = 0;
labelName.text = #"Your String...";
[self.view addSubview:labelName];
You can do that via the Storyboard too:
Select the Label on the view controller
In the Attribute Inspector, increase the value of the Line option (Press Alt+Cmd+4 to show Attributes Inspector)
Double click the Label in the view controller and write or paste your text
Resize the Label and/or increase the font size so that the whole text could be shown
you should try this:
-(CGFloat)dynamicLblHeight:(UILabel *)lbl
{
CGFloat lblWidth = lbl.frame.size.width;
CGRect lblTextSize = [lbl.text boundingRectWithSize:CGSizeMake(lblWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:lbl.font}
context:nil];
return lblTextSize.size.height;
}
Oh, in 2021 I'm trapped by a label text unable to change lines for 1 hour, then realize I forget to set label's width, WTF.
let stepLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.text = "Put your device and computer under same Wi-Fi network."
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(stepLabel)
NSLayoutConstraint.activate([
stepLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stepLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
stepLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.7)
])
}
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 30)];
[textLabel sizeToFit];
textLabel.numberOfLines = 0;
textLabel.text = #"Your String...";
Already answered, but you can do it manually in the storyboard too. Under Attributes Inspector for the Label, you can change Line Breaks to Word Wrap (or character wrap).
In this function pass string that you want to assign in label and pass font size in place of self.activityFont and pass label width in place of 235, now you get label height according to your string.
it will work fine.
-(float)calculateLabelStringHeight:(NSString *)answer
{
CGRect textRect = [answer boundingRectWithSize: CGSizeMake(235, 10000000) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:self.activityFont} context:nil];
return textRect.size.height;
}
Set below either in code or in storyboard itself
Label.lineBreakMode = NSLineBreakByWordWrapping;
Label.numberOfLines = 0;
and please don't forget to set left, right, top and bottom constraints for label otherwise it won't work.
On C#, this worked for me inside UITableViewCell.
UILabel myLabel = new UILabel();
myLabel.Font = UIFont.SystemFontOfSize(16);
myLabel.Lines = 0;
myLabel.TextAlignment = UITextAlignment.Left;
myLabel.LineBreakMode = UILineBreakMode.WordWrap;
myLabel.MinimumScaleFactor = 1;
myLabel.AdjustsFontSizeToFitWidth = true;
myLabel.InvalidateIntrinsicContentSize();
myLabel.Frame = new CoreGraphics.CGRect(20, mycell.ContentView.Frame.Y + 20, cell.ContentView.Frame.Size.Width - 40, mycell.ContentView.Frame.Size.Height);
myCell.ContentView.AddSubview(myLabel);
I think the point here is:-
myLabel.TextAlignment = UITextAlignment.Left;
myLabel.LineBreakMode = UILineBreakMode.WordWrap;
myLabel.MinimumScaleFactor = 1;
myLabel.AdjustsFontSizeToFitWidth = true;
This code is returning size height according to text
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font
{
CGFloat result = font.pointSize+4;
if (text)
{
CGSize size;
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, 999)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
size = CGSizeMake(frame.size.width, frame.size.height+1);
result = MAX(size.height, result); //At least one row
}
return result;
}
How do I add a badge to UITableViewCell, like this:
alt text http://img17.imageshack.us/img17/9974/img0001ac9.png
Should I simply add a subview with a text and label on it?
Here's a swift enhancement to #POF's answer. We don't need as many subviews and we can use math to support N digits, not just 1-3:
func setDiscountBadge(count: Int) {
let size: CGFloat = 26
let digits = CGFloat( count("\(number)") ) // digits in the label
let width = max(size, 0.7 * size * digits) // perfect circle is smallest allowed
let badge = UILabel(frame: CGRectMake(0, 0, width, size))
badge.text = "\(number)"
badge.layer.cornerRadius = size / 2
badge.layer.masksToBounds = true
badge.textAlignment = .Center
badge.textColor = UIColor.whiteColor()
badge.backgroundColor = cfg.UIColors.brand
YOURCELL.accessoryView = badge // !! change this line
}
And the result (I use a brand color, but yours can be any color):
TDBadgedCell is a pretty good choice. Highly customizable for your needs.
As for me the simplest way is to use cell.accessoryView. Please look into my code how I did it:
UIImageView * commentsViewBG = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"counter1.png"]];
commentsViewBG.frame = CGRectMake(
commentsViewBG.frame.origin.x,
commentsViewBG.frame.origin.y, 30, 20);
UILabel *commentsCount;
if (commentsArray.totalCount < 10)
commentsCount = [[UILabel alloc]initWithFrame:CGRectMake(10, -10, 40, 40)];
else if (commentsArray.totalCount < 100)
commentsCount = [[UILabel alloc]initWithFrame:CGRectMake(5, -10, 40, 40)];
else if (commentsArray.totalCount < 1000)
{
commentsViewBG.frame = CGRectMake(
commentsViewBG.frame.origin.x,
commentsViewBG.frame.origin.y, 40, 20);
commentsCount = [[UILabel alloc]initWithFrame:CGRectMake(5, -10, 40, 40)];
}
commentsCount.text = [NSString stringWithFormat:#"%ld",(long)commentsArray.totalCount];
commentsCount.textColor = [UIColor whiteColor];
commentsCount.backgroundColor = [UIColor clearColor];
[commentsViewBG addSubview:commentsCount];
cell.accessoryView = commentsViewBG;
And my result:
Hope it helps.
Yes, there is currently no supported way of adding a badge to a UITableView Cell. In this example, it is most likely a custom subview which contains an image and UILabel.
I'd like to add another alternative to create customized Badges. CustomBadge is a little bit more powerful. It's open and for free.