Creación de UIButton (UIButtonTypeCustom) con una image en la parte superior y label en la parte inferior con AutoLayout

Estoy intentando mostrar el button con un text (línea simple / múltiple) en la parte inferior e image (debe parecer circular) en la parte superior; la image y el text se deben resaltar onclick. Me gusta esto:

Botón deseado con imágenes

Aquí está el código en viewDidLoad :

 btArtAndPainting = [UIButton buttonWithType:UIButtonTypeCustom]; btArtAndPainting.backgroundColor = [[UIColor cyanColor] colorWithAlphaComponent:1.00f]; btArtAndPainting.translatesAutoresizingMaskIntoConstraints = NO; self.vwContainer.translatesAutoresizingMaskIntoConstraints = NO; [self.vwContainer addSubview:btArtAndPainting]; [btArtAndPainting setImage:[UIImage imageNamed:kIMGCategoryArtAndPaintingNormal] forState:UIControlStateNormal]; [btArtAndPainting setImage:[UIImage imageNamed:kIMGCategoryArtAndPaintingHighlighted] forState:UIControlStateHighlighted]; [btArtAndPainting setTitle:@"Art and Painting" forState:UIControlStateNormal]; [btArtAndPainting setTitle:@"Art and Painting" forState:UIControlStateHighlighted]; btArtAndPainting.tintColor = [UIColor networkingColor]; btArtAndPainting.titleLabel.font = [UIFont systemFontOfSize:10.00f]; btArtAndPainting.titleLabel.textColor = [UIColor whiteColor]; btArtAndPainting.titleLabel.textAlignment = NSTextAlignmentCenter; btArtAndPainting.titleLabel.lineBreakMode = NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail; btArtAndPainting.titleLabel.numberOfLines = 0; btArtAndPainting.imageEdgeInsets = UIEdgeInsetsMake(0.00f, 8.00f, 20.00f, 8.00f); btArtAndPainting.titleEdgeInsets = UIEdgeInsetsMake(32.00f, 0.00f, 0.00f, 0.00f); NSArray *constraintsWidth = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[btArtAndPainting(60)]|" options:0 metrics:nil views:viewDictionary]; NSArray *constraintsHeight = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[searchBar]-10-[btArtAndPainting(60)]" options:0 metrics:nil views:viewDictionary]; [self.vwContainer addConstraints:constraintsHeight]; [self.vwContainer addConstraints:constraintsWidth]; [btArtAndPainting layoutIfNeeded]; [btArtAndPainting needsUpdateConstraints]; 

El problema es que el text no se muestra en absoluto (en estados normales y resaltados). Vea las imágenes enlazadas a continuación. ¿Cómo utilizo UIEdgeInset para dar cabida al text? También he intentado crear una categoría de UIButton pero el efecto es más o less el mismo.

Botón normal

Utilice el código siguiente para configurar el recuadro,

 CGFloat spacing = 1.0; CGSize imageSize = btArtAndPainting.imageView.frame.size; btArtAndPainting.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing), 0.0); CGSize titleSize = btArtAndPainting.titleLabel.frame.size; btArtAndPainting.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width); 

Espero que esto ayude..

He encontrado esta situación tantas veces, que decidí escribir un UIB personalizado que admite una alignment flexible en pocas líneas de código.
Está disponible aquí: https://github.com/namanhams/FlexibleAlignButton

Ejemplo:
self.btn.alignment = kButtonAlignmentLabelBottom; self.btn.gap = 5; // vertical gap between image and text

Aquí está mi solución al problema. Se creó una subclass UIButton y se anulan los layoutSubviews ()

 import UIKit @IBDesignable class ImageTopButton: UIButton { override func layoutSubviews() { super.layoutSubviews() let size = self.frame.size let imageSize = self.imageView!.intrinsicContentSize() let labelSize = self.titleLabel!.intrinsicContentSize() let totalHeight = imageSize.height + labelSize.height let heightDiff = size.height - totalHeight let padding = heightDiff / 2 self.imageView!.center = CGPoint(x: size.width / 2, y: imageSize.height / 2 + padding) self.titleLabel!.center = CGPoint(x: size.width / 2, y: imageSize.height + padding + labelSize.height / 1.5) } }