2012-06-08 5 views
37

Я видел сообщения о правильном выравнивании, но я не могу получить выравнивание по левому краю. Я хочу, чтобы кнопка занимала ширину экрана, с изображением слева и заголовком/текстом в центре.Выравнивание по левому краю изображения и центра текста на UIButton

Это не работает (по крайней мере, надежно):

button.titleLabel.textAlignment = UITextAlignmentCenter; 
    [button setImageEdgeInsets:UIEdgeInsetsMake(0, -60.0, 0, 0)]; 
    button.frame = CGRectMake((self.view.frame.size.width - w)/2, self.view.frame.size.height - 140.0, self.view.frame.size.width - 10.0, 40.0); 

ответ

0

Это может быть лучше, чтобы создать пользовательский подкласс UIButton для решения этой проблемы, в лучшем образом. Apple может «перезагрузить» ваши настройки.

1

1) button.frame = self.view.bounds;

2) setImageEdgeInsets с отрицательными значениями, когда ваша кнопка заполняет экран, это безумие. Пересмотрите, что вы пытаетесь сделать здесь?

3) UITextAlignmentCenter теперь NSTextAlignmentCenter

4) button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

38

В моем конце концов, я сделал это с помощью UIEdgeInsetsMake которой левый угол рассчитывается, чтобы сделать его в центр. Я не уверен, есть ли что-то действительно, вы можете сделать текст выровненным по центру, но это работает для меня. Убедитесь, что вы установили левый угол в нужное положение, вычислив ширину. например UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f)

UIButton *scanBarCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
scanBarCodeButton.frame = CGRectMake(center, 10.0f, fieldWidth, 40.0f); 
[scanBarCodeButton setImage:[UIImage imageNamed:@"BarCodeIcon.png"] forState:UIControlStateNormal]; 
[scanBarCodeButton setTitle:@"Scan the Barcode" forState:UIControlStateNormal]; 
scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f); 
[scanBarCodeButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 
[scanBarCodeButton addTarget:self action:@selector(scanBarCode:) forControlEvents:UIControlEventTouchUpInside]; 
[self.view addSubview:scanBarCodeButton]; 

Результат выглядит,

centered text with image http://i43.tinypic.com/33mbxxi.png

В Swift:

var scanBarCodeButton: UIButton = UIButton(type: .roundedRect) 
scanBarCodeButton.frame = CGRectMake(center, 10.0, fieldWidth, 40.0) 
scanBarCodeButton.setImage(UIImage(named: "BarCodeIcon.png"), for: UIControlStateNormal) 
scanBarCodeButton.setTitle("Scan the Barcode", for: UIControlStateNormal) 
scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0, 42.0, 0.0, 0.0) 
scanBarCodeButton.contentHorizontalAlignment = .left 
scanBarCodeButton.addTarget(self, action: "scanBarCode:", for: UIControlEventTouchUpInside) 
self.view.addSubview(scanBarCodeButton) 
+0

Спасибо! Именно то, что я искал. –

+4

Вынос здесь для меня состоял в том, чтобы установить горизонтальное выравнивание содержимого влево, а не по умолчанию. Сам текст по-прежнему сосредоточен в области текста. Ваше магическое число «42» здесь - это ширина изображения, легко вычисляемая. –

6

Создайте свою кнопку и установить выравнивание текста по центру, а затем добавить:

UIImage *image = [UIImage imageNamed:@"..."]; 
CGSize imageSize = image.size; 
CGFloat offsetY = floor((self.layer.bounds.size.height - imageSize.height)/2.0); 

CALayer *imageLayer = [CALayer layer]; 
imageLayer.contents = (__bridge id) image.CGImage; 
imageLayer.contentsGravity = kCAGravityBottom; 
imageLayer.contentsScale = [UIScreen mainScreen].scale; 
imageLayer.frame = CGRectMake(offsetY, offsetY, imageSize.width, imageSize.height); 
[self.layer addSublayer:imageLayer]; 
7

Как я думаю, хорошее решение должно быть полезно для любого текста без жестко заданных значений для вложений (речь идет о решении, предоставленном toytoy). Я использую код, подобный этому:

NSString *sometitle = @"blabla button title"; 
NSString *someimage = @"blablaimage"; 
UIImage *image = [[UIImage imageNamed:someimage]; 
int buttonWidth = A; 
int buttonHeight = B; 
int imageWidth =image.size.width; 
int imageHeight = image.size.height; 
int titleWidth = buttonWidth - imageWidth; 

// create button and set image and title 
buttonView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonWidth, buttonHeight)]; 
[buttonView setImage:image forState:UIControlStateNormal]; 
[buttonView setTitle:sometitle forState:UIControlStateNormal]; 

// make button all content to be left aligned 
[buttonView setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 

// set title font 
[buttonView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:14]]; 

// calculate font text width with selected font 
CGSize stringBoundingBox = [number sizeWithFont:[buttonView.titleLabel font]]; 

// make title inset with some value from left 
// it place the title right on the center of space for the title 
int titleLeft = (titleWidth - stringBoundingBox.width)/2; 
[buttonView setTitleEdgeInsets:UIEdgeInsetsMake(0, titleLeft, 0, 0)]; 

После строки с stringBoundingBox инициализации Я также добавить несколько строк, как это:

if (stringBoundingBox.width > titleWidth) 
{ 
    [_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:13]]; 
    stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]]; 
} 
if (stringBoundingBox.width > titleWidth) 
{ 
    [_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:12]]; 
    stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]]; 
} 

это позволило мне установить заголовки дольше, чем доступное пространство, выбрав некоторые более мелкие шрифты. Я делаю это, потому что другого пути для этого:

[buttonView.titleLabel setAdjustsFontSizeToFitWidth:YES]; 

работает не очень хорошо, выглядит он взят размер шрифта на 3-4 пунктов меньше на один шаг, так что некоторые не так долго линии становятся слишком меньше, чем это должно быть.

Этот код позволяет нам помещать любой текст в пространство заголовка кнопки точно в центре.

1

Я вижу здесь много решений, которые фокусируются на установке значка слева. Я думаю, что проще просто добавить UIImageView, выровнять левую часть кнопки и изображение и центрировать их вместе. Затем вы можете немного поиграть со смещением, чтобы он выглядел красиво.

Нет кода, все в интерфейсе Builder.

+0

Да, но будет ли это изображение реагировать на касания пользователя, как изменение цвета? – vedrano

+0

Вы можете использовать цвет оттенков на всех изображениях, но по умолчанию он не включен: http://stackoverflow.com/questions/22170688/using-tint-color-on-uiimageview –

+0

Я думаю, вы правы. Таким образом, вы предполагаете, что приложение должно переопределить метод setSelected() и поддерживать внешний вид изображения вручную (не по умолчанию). – vedrano

4

Это хорошо работает для меня, нескольких кнопок, с различной шириной изображения и разной длиной заголовка:

Подклассом UIButton, и добавьте следующий метод:

override func layoutSubviews() { 
    super.layoutSubviews() 

    if let image = imageView?.image { 

     let margin = 30 - image.size.width/2 
     let titleRect = titleRectForContentRect(bounds) 
     let titleOffset = (bounds.width - titleRect.width - image.size.width - margin)/2 


     contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left 
      imageEdgeInsets = UIEdgeInsetsMake(0, margin, 0, 0) 
      titleEdgeInsets = UIEdgeInsetsMake(0, (bounds.width - titleRect.width - image.size.width - margin)/2, 0, 0) 
    } 

} 
+0

Что с магическим номером 30? –

+0

@JefferyThomas Это просто запас. он работает хорошо для меня с разным размером изображения с помощью этого метода. –

0

Один трюк заключается в следующем:

  1. Override titleRectForContentRect сделать titleLabel баттона «s frame равным пределах от кнопки
  2. Установите titleLabel «s textAlignment к .Center
  3. переопределение imageRectForContentRect указать origin.x от кнопки он imageView

    import UIKit 
    
    class ButtonWithLeftAlignedImageAndCenteredText: UIButton { 
    
        override init(frame: CGRect) { 
         super.init(frame: frame) 
    
         titleLabel?.textAlignment = .Center 
        } 
    
        override func imageRectForContentRect(contentRect: CGRect) -> CGRect { 
         var imageFrame = super.imageRectForContentRect(contentRect) 
         imageFrame.origin.x = 20 //offset from left edge 
         return imageFrame 
        } 
    
        override func titleRectForContentRect(contentRect:CGRect) -> CGRect { 
         var titleFrame = super.titleRectForContentRect(contentRect) 
         titleFrame = self.bounds 
         return titleFrame 
        } 
    
    
        required init?(coder aDecoder: NSCoder) { 
         fatalError("init(coder:) has not been implemented") 
        } 
    } 
    
0

Вы можете использовать ниже код для выравнивания влево изображение на UIButton: -

Этап 1:

//create your UIButton 
UIButton *post_bNeeds_BTN= [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
post_bNeeds_BTN.frame= CGRectMake(160 ,5 ,150 ,40); 
[post_bNeeds_BTN addTarget:self action:@selector(post_Buying_Needs_BTN_Pressed:) forControlEvents:UIControlEventTouchUpInside]; 
[post_bNeeds_BTN setBackgroundColor:[UIColor colorWithRed:243/255.0 green:131/255.0 blue:26/255.0 alpha:1.0f]];//230 
[self.view addSubview:post_bNeeds_BTN]; 
post_bNeeds_BTN.autoresizingMask= UIViewAutoresizingFlexibleWidth; 

Шаг 2:

//Add UIImageView on right side the button 
UIImageView *bNeedsIVw= [[UIImageView alloc] initWithFrame:CGRectMake(5,5,30,30)]; 
bNeedsIVw.image= [UIImage imageNamed:@"postRequir_30.png"]; 
bNeedsIVw.image= [bNeedsIVw.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 
bNeedsIVw.tintColor= [UIColor whiteColor]; 
[post_bNeeds_BTN addSubview:bNeedsIVw]; 

Шаг 3:

//also set UILable on UIButton 
UILabel *bNeedsLbl= [[UILabel alloc] initWithFrame:CGRectMake(40 ,0 ,post_Prod_BTN.frame.size.width-40 ,post_Prod_BTN.frame.size.height)]; 
bNeedsLbl.text= @"Requirements"; 
bNeedsLbl.font= [UIFont systemFontOfSize:16]; 
bNeedsLbl.textColor= [UIColor whiteColor]; 
bNeedsLbl.textAlignment= NSTextAlignmentLeft; 
[post_bNeeds_BTN addSubview:bNeedsLbl]; 

Шаг 4:

-(void)post_Buying_Needs_BTN_Pressed:(id)sender{ 
    //write your code action here,, 
} 

спасибо,

1

я написал расширение UIButton в скор -

extension UIButton { 

func setLeftImage(imageName:String, padding:CGFloat) { 
     //Set left image 
     let image = UIImage(named: imageName) 
     self.setImage(image, forState: .Normal) 

     //Calculate and set image inset to keep it left aligned 
     let imageWidth = image?.size.width 
     let textWidth = self.titleLabel?.intrinsicContentSize().width 
     let buttonWidth = CGRectGetWidth(self.bounds) 

     let padding:CGFloat = 30.0 
     let rightInset = buttonWidth - imageWidth! - textWidth! - padding 

     self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: rightInset) 
    } 
} 

Я бы нарисовал текст своей кнопки любым способом, я хочу, держите его в центре. Тогда я бы назвал этот метод моей кнопки как -

myButton.setLeftImage("image_name", 30.0) 

это привело бы к моему образу, чтобы оставить совмещена с некоторой прокладкой из левой границы.

3
[self.button setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal]; 

[self.button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, self.button.center.x/2 , 0.0, 0.0)]; 

[self.button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 

Дайте мне знать, если они не работают.

Моего выход enter image description here

+0

Текст не центрирован, он сдвигается вправо по изображению –

+0

Затем вы можете изменить значения UIEdgeInsetsMake. Просто попробуйте. –

0

этот код делает ваше изображение кнопки, чтобы выровнять влево, и название метка перемещается в центр кнопки. б кнопка :)

  b.contentHorizontalAlignment = .Left 
     let left = (b.frameWidth() - b.titleLabel!.frameWidth())/2 - CGRectGetMaxX(b.imageView!.frame) 
     b.titleEdgeInsets = UIEdgeInsetsMake(0, left, 0, 0) 
34

Это решение работает с Swift 3 и уважает оригинальный контент и края изображения врезки, сохраняя при этом указанное в заголовке метку всегда, расположенную в центре свободного пространства, что делает намного проще регулировочные поля.

Он переопределяет titleRect(forContentRect:) метод и возвращает правильный кадр:

@IBDesignable 
class LeftAlignedIconButton: UIButton { 
    override func titleRect(forContentRect contentRect: CGRect) -> CGRect { 
     let titleRect = super.titleRect(forContentRect: contentRect) 
     let imageSize = currentImage?.size ?? .zero 
     let availableWidth = contentRect.width - imageEdgeInsets.right - imageSize.width - titleRect.width 
     return titleRect.offsetBy(dx: round(availableWidth/2), dy: 0) 
    } 
} 

следующие углублени:

enter image description here

результат будет в этом:

enter image description here


Устаревшее предыдущий ответ

Это работает в большинстве случаев, но некоторые макеты вызывают layoutSubviews рекурсивно вызывать себя в бесконечном цикле, так использовать с осторожностью.

@IBDesignable 
class LeftAlignedIconButton: UIButton { 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     contentHorizontalAlignment = .left 
     let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets) 
     let availableWidth = availableSpace.width - imageEdgeInsets.right - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0) 
     titleEdgeInsets = UIEdgeInsets(top: 0, left: availableWidth/2, bottom: 0, right: 0) 
    } 
} 

Этот код будет делать то же самое, но совместив значок к правому краю:

@IBDesignable 
class RightAlignedIconButton: UIButton { 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     semanticContentAttribute = .forceRightToLeft 
     contentHorizontalAlignment = .right 
     let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets) 
     let availableWidth = availableSpace.width - imageEdgeInsets.left - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0) 
     titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: availableWidth/2) 
    } 
} 

enter image description here

Правая версия правка использует semanticContentAttribute поэтому она требует IOS 9+.

+0

Я считаю, что frame.width должен быть frame.size.width – SArnab

+0

@SArnab 'frame.width' правильный https://developer.apple.com/reference/coregraphics/cgrect/1454758-width – redent84

+0

И вот я постоянно погружение в размер. Благодаря! – SArnab

1

Я знаю, что этот ответ любопытен. Но у меня есть очень простое решение для людей, которые хотят добавить изображение, используя UIImageView, в левой части UIButton с центрированным текстом. Все программно

class RandomVC: UIViewController{ 

    var imageDemo: UIImageView = { 
    let img = UIImageView() 
    img.translatesAutoresizingMaskIntoConstraints = false 
    img.image = UIImage(named: "someImgFromAssets") 
    return img 
    }() 

    lazy var someButton: UIButton = { //lazy var: so button can have access to self class 
    let button = UIButton(type: .system) 
    button.setTitle("This is your title", for: UIControlState.normal) 
    button.translatesAutoresizingMaskIntoConstraints = false 
    button.setTitleColor(UIColor.white, for: UIControlState.normal) 
    button.addTarget(self, action: #selector(handleButtonClick), for: .touchUpInside) //make sure you write function "handleButtonClick" inside your class 
    button.titleLabel?.textAlignment = .center 
    return button 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     view.addSubView(someButton) 
     someButton.addSubview(imageDemo) 
     imageDemo.centerYAnchor.constraint(equalTo: someButton.centerYAnchor).isActive = true 
     imageDemo.leftAnchor.constraint(equalTo: someButton.leftAnchor, constant: 10).isActive = true 
     imageDemo.heightAnchor.constraint(equalToConstant: 25).isActive = true 
     imageDemo.widthAnchor.constraint(equalToConstant: 25).isActive = true 
    } 

} 
2

Я написал расширение UIButton.

extension UIButton { 

    /// Add image on left view 
    func leftImage(image: UIImage) { 
    self.setImage(image, for: .normal) 
    self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width) 
    } 
} 

И вы могли бы использовать так:

yourButton.leftImage(image: yourImage) 

Вуаля!

Смежные вопросы