Bagaimana cara menempatkan gambar di sisi kanan teks dalam UIButton?


300

Saya tidak ingin menggunakan subview jika saya bisa menghindarinya. Saya ingin UIButtondengan gambar latar belakang, teks, dan gambar di dalamnya. Saat ini, ketika saya melakukan itu, gambar ada di sisi kiri teks. Gambar latar belakang, teks, dan gambar semuanya memiliki status sorotan yang berbeda.


Untuk menambahkan "retasan" lain ke daftar yang sedang tumbuh di sini: Anda dapat mengatur atribut tombol Judul ke string yang dikaitkan berisi judul tombol Anda + spasi + gambar (sebagai NSTextAttachment). Anda mungkin perlu mengubah batas lampiran untuk membuatnya sejajar seperti yang Anda inginkan (lihat stackoverflow.com/questions/26105803/… ).
Manav

Jawaban:


266

Meskipun beberapa jawaban yang disarankan sangat kreatif dan sangat pintar, solusi paling sederhana adalah sebagai berikut:

button.semanticContentAttribute = UIApplication.shared
    .userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft

Sesimpel itu. Sebagai bonus, gambar akan berada di sisi kiri di lokal kanan-ke-kiri.

EDIT : karena pertanyaan telah ditanyakan beberapa kali, ini adalah iOS 9+ .


89
Saya tidak percaya jawaban ini yang diterima. Tidak ada yang melakukan lokalisasi untuk aplikasi mereka?
Zoltán

6
@ palzoltan: ini menjawab pertanyaan (mis. "Bagaimana cara menempatkan gambar di sisi kanan teks dalam UIButton?"). Apa hubungan lokalisasi dengan ini?
Benjamin

17
Tidak ada banyak situasi ketika Anda tidak ingin tata letak Anda "terbalik" dalam bahasa RTL. Pengaturan langsung semanticContentAttributehanyalah hack / solusi, bukan solusi nyata.
Zoltán

6
Pendekatan saya adalah Anda tidak tahu apa yang dibuat oleh orang yang mengajukan pertanyaan, jadi selalu lebih baik hitung dengan fleksibilitas untuk tata letak.
Zoltán

2
@ Lokalisasi Zoltán bukan masalah, cukup balikkan properti tergantung pada lokal saat ini.
manmal

561

Solusi paling sederhana:

iOS 10 & lebih tinggi, Swift:

button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

Sebelum iOS 10, Swift / Obj-C:

button.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

8
Saya menggunakan ini untuk tampilan judul bar navigasi dan ada kesalahan. Tidak apa-apa saat pertama kali dimuat, tetapi ketika Anda mendorong pengontrol tampilan dan pop itu, judul akan terbalik.
funct7

@WoominJoshPark Menarik ... Saya hanya bisa menebak bahwa ini adalah karena transformasi tersebut animasi secara internal untuk animasi pop navigasi.
Liau Jian Jie

1
Saya menemukan jika ini menyebabkan keluhan tentang konflik kendala autolayout saat runtime mungkin diperbaiki dengan menambahkan ini di layoutSubviews ()
Vlad

1
Bagaimana saya bisa menempatkan lebih banyak ruang di antara teks dan gambar?
rohinb

2
@rohinb @ jose920405 Cobalah mengatur ImageEdgeInsets dan ContentEdgeInsets untuk padding (dengan mengingat mereka telah terbalik). Sebagai contoh button.ImageEdgeInsets = new UIEdgeInsets(0, -leftPadding, 0, leftPadding); button.ContentEdgeInsets = new UIEdgeInsets(0, 0, 0, leftPadding);. Itu di Xamarin, tetapi harus menerjemahkan ke Swift / Obj-C dengan cukup mudah.
Lee Richardson

269

DIPERBARUI UNTUK XCODE 9 (Via Interface Builder)

Ada cara yang lebih mudah dari Interface Builder .

Pilih UIButton dan pilih opsi ini di View Utilities> Semantic :

kiri ke kanan masukkan deskripsi gambar di sini Itu dia! Bagus dan sederhana!

OPSIONAL - langkah ke-2:

Jika Anda ingin menyesuaikan jarak antara gambar dan judul, Anda dapat mengubah Image Inset di sini:

masukkan deskripsi gambar di sini

Semoga itu bisa membantu!


2
Dalam Xcode 9.0 beta 5 (9M202q), Anda sayangnya hanya melihat hasilnya saat runtime — di storyboard masih menampilkan gambar ke kiri. Perhatikan juga bahwa karena ini diperlukan beberapa percobaan dan kesalahan untuk mengatur inset yang benar.
PDK

3
Tolong jangan lakukan ini dengan cara - ini melanggar lokalisasi untuk bahasa kanan-ke-kiri.
jsadler

169

Subclassing UIButton sama sekali tidak perlu. Alih-alih, Anda cukup menetapkan nilai inset kiri tinggi untuk inset gambar, dan inset kanan kecil untuk judul. Sesuatu seperti ini:

button.imageEdgeInsets = UIEdgeInsetsMake(0., button.frame.size.width - (image.size.width + 15.), 0., 0.);
button.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., image.size.width);

3
Berhasil, tetapi ingatlah bahwa hari ini dengan autolayout Anda harus melakukannya di viewDidAppear dan bukan di viewDidLoad
Hola Soy Edu Feliz Navidad

91

Saya memberi Inspire48 penghargaan untuk yang satu ini. Berdasarkan sarannya dan melihat pertanyaan lain itu saya menemukan ini. Subclass UIButton dan timpa metode ini.

@implementation UIButtonSubclass

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super imageRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) -  self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMinX(frame) - CGRectGetWidth([self imageRectForContentRect:contentRect]);
    return frame;
}

@end

3
UIButton adalah kluster kelas dan tidak boleh disubklasifikasikan.
Scott Berrevoets

50
Itu tidak benar, dokumentasi secara eksplisit menyebutkan subclassing dan memberikan metode yang Anda harus timpa untuk perilaku tata letak kustom.
Tark

2
developer.apple.com/library/ios/documentation/uikit/reference/… buttonWithType If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directly dan backgroundRectForBoundsSubclasses yang memberikan perhiasan latar belakang kustom dapat menggantikan metode ini dan mengembalikan persegi batas yang dimodifikasi untuk mencegah tombol dari menggambar konten kustom apa pun. `Tidak ada yang menyebutkan spesifik metode, tapi saya berasumsi mereka tidak keberatan subclass.
christophercotton

1
Sepertinya rumus ini lebih baik untuk mirroring bingkai foto: frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) - self.imageEdgeInsets.right + self.imageEdgeInsets.left - frame.origin.x;Ini bekerja lebih baik untuk UIControlContentHorizontalAlignmentCenterdan lain-lain ...
k06a

@ GwendalRoué Hanya karena lebih pendek bukan berarti lebih baik. Ini cara peretasan, dan itu membuat tombol mengabaikan insets aktual, dan mungkin pecah dalam bahasa kanan-ke-kiri. Dengan jawaban ini Anda memiliki kontrol penuh terhadap tata letak
Accatyyc

76

Perbarui saja insets ketika judul diubah. Anda perlu mengkompensasi inset dengan inset yang sama dan berlawanan di sisi lain.

[thebutton setTitle:title forState:UIControlStateNormal];
thebutton.titleEdgeInsets = UIEdgeInsetsMake(0, -thebutton.imageView.frame.size.width, 0, thebutton.imageView.frame.size.width);
thebutton.imageEdgeInsets = UIEdgeInsetsMake(0, thebutton.titleLabel.frame.size.width, 0, -thebutton.titleLabel.frame.size.width);

3
Anda mungkin ingin menambahkan [thebutton.titleLabel sizeToFit];sebelumnya. Lebar mungkin nol jika Anda belum memicu tata letak. Hal yang sama berlaku untuk ukuran gambar (cukup gunakan ukuran UIImage.size daripada ukuran imageView)
delrox

@delrox poin bagus. Dapat menggunakan titleWidth = [self.titleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height)].width;(atau jika Anda khawatir tentang bingkai tombol yang belum dibuat, gunakan CGFLOAT_MAX untuk ketinggian juga) danimageWidth = self.currentImage.size.width;
Dave Goldman

1
Bekerja dengan sempurna pada viewDidLayoutSubviews
Gwendal Roué

Saya harus menempatkan ini di layoutSubviewsdalam UITableViewCellsubkelas saya tetapi ini bekerja dengan baik. Terima kasih!
RyanG

60

Semua jawaban ini, per Januari 2016, tidak perlu. Di Interface Builder, atur Tampilan Semantic ke Force Right-to-Left, atau jika Anda lebih suka cara terprogram, semanticContentAttribute = .forceRightToLeftItu akan menyebabkan gambar muncul di sebelah kanan teks Anda.


5
Sayangnya itu tidak mendukung ios lebih dari 9. Masih jawaban yang bagus, tho.
Eddie

1
Saya sedih melaporkan, bahwa pengaturan ini pada UIButton yang kemudian digunakan untuk UIBarButtonItem tidak menghasilkan perubahan apa pun.
Amelia

Seperti @Amelia sebutkan, itu tidak berfungsi jika Anda menelepon UIBarButtonItem(customView: button), tetapi akan bekerja jika Anda membungkus tombol di dalam beberapa tampilan kosong
tt.Kilew

@ tt.Kilew, menggunakan XCode 8.1 Anda membuatnya berfungsi. Saya mengatur uiButton.semanticContentAttribute = .forceRightToLeft dan memberikan nextButton = UIBarButtonItem (customView: uiButton)
Eugene Biryukov


25

Pembaruan: Swift 3

class ButtonIconRight: UIButton {
    override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRect(forContentRect: contentRect)
        imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
    }

    override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRect(forContentRect: contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
        }
        return titleFrame
    }
}

Jawaban asli untuk Swift 2:

Sebuah solusi yang menangani semua perataan horizontal, dengan contoh implementasi Swift. Cukup terjemahkan ke Objective-C jika perlu.

class ButtonIconRight: UIButton {
    override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRectForContentRect(contentRect)
        imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
        return imageFrame
    }

    override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRectForContentRect(contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
        }
        return titleFrame
    }
}

Juga perlu dicatat bahwa ia menangani insets gambar & judul dengan cukup baik.

Terinspirasi dari jawaban jasongregori;)


1
Solusi ini bekerja untuk saya, namun gambar saya memerlukan beberapa ruang di sekitarnya, jadi saya menambahkan kode berikut: self.contentEdgeInsets = UIEdgeInsetsMake (10.0, 10.0, 10.0, 10.0)
user1354603

1
Saya suka cara ini karena Anda dapat menambah @IBDesignablekelas dan melihatnya terbalik pada waktu desain.
James Toomey

Saya lebih suka solusi ini karena bahkan berfungsi ketika diletakkan di bilah navigasi.
El Horrible

10

Jika ini perlu dilakukan di UIBarButtonItem , pembungkus tambahan harus digunakan.
Ini akan berfungsi

let view = UIView()
let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
view.addSubview(button)
view.frame = button.bounds
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: view)

Ini tidak akan berhasil

let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

7

Inilah solusi untuk UIButtondengan konten yang selaras dengan pusat. Kode ini membuat gambar disejajarkan dengan benar dan memungkinkan untuk digunakan imageEdgeInsetsdan titleEdgeInsetsuntuk penentuan posisi yang berharga.

masukkan deskripsi gambar di sini

Subkelas UIButtondengan kelas khusus Anda dan tambahkan:

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    CGRect frame = [super imageRectForContentRect:contentRect];
    CGFloat imageWidth = frame.size.width;
    CGRect titleRect = CGRectZero;
    titleRect.size = [[self titleForState:self.state] sizeWithAttributes:@{NSFontAttributeName: self.titleLabel.font}];
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect {
    CGFloat imageWidth = [self imageForState:self.state].size.width;
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    return frame;
}

1
Anda juga dapat menambahkan IBDESIGNABLE ke header kelas untuk menontonnya di storyborad yadi.sk/i/fd6Si-BJqzCFD
Nikolay Shubenkov

6

Karena solusi transformasi tidak berfungsi di iOS 11, saya memutuskan untuk menulis pendekatan baru.

Menyesuaikan tombol semanticContentAttribute memberi kita gambar dengan baik ke kanan tanpa harus menyampaikan jika teks berubah. Karena inilah solusi ideal. Namun saya masih membutuhkan dukungan RTL. Fakta bahwa suatu aplikasi tidak dapat mengubah arah tata letak dalam sesi yang sama menyelesaikan masalah ini dengan mudah.

Dengan itu, itu cukup lurus ke depan.

extension UIButton {
    func alignImageRight() {
        if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
            semanticContentAttribute = .forceRightToLeft
        }
        else {
            semanticContentAttribute = .forceLeftToRight
        }
    }
}

6

Ekstensi jalan

Menggunakan ekstensi untuk mengatur gambar di sisi kanan dengan offset khusus

   extension UIButton {
    func addRightImage(image: UIImage, offset: CGFloat) {
        self.setImage(image, for: .normal)
        self.imageView?.translatesAutoresizingMaskIntoConstraints = false
        self.imageView?.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true
        self.imageView?.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -offset).isActive = true
    }
}

4

Swift -Tambah UiButton dan masukkan baris-baris ini

    if let imageWidth = self.imageView?.frame.width {
        self.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth);
    }

    if let titleWidth = self.titleLabel?.frame.width {
        let spacing = titleWidth + 20
        self.imageEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, -spacing);
    }

3

Membangun solusi elegan Piotr Tomasik: jika Anda ingin memiliki sedikit jarak antara label tombol dan gambar juga, maka sertakan dalam insets tepi Anda sebagai berikut (menyalin kode saya di sini yang berfungsi dengan baik untuk saya):

    CGFloat spacing          = 3;
    CGFloat insetAmount      = 0.5 * spacing;

    // First set overall size of the button:
    button.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
    [button sizeToFit];

    // Then adjust title and image insets so image is flipped to the right and there is spacing between title and image:
    button.titleEdgeInsets   = UIEdgeInsetsMake(0, -button.imageView.frame.size.width - insetAmount, 0,  button.imageView.frame.size.width  + insetAmount);
    button.imageEdgeInsets   = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width + insetAmount, 0, -button.titleLabel.frame.size.width - insetAmount);

Terima kasih Piotr untuk solusi Anda!

Erik


@ Lulian: Saya baru-baru ini menggunakan solusi Liau Jian Jie (jawaban yang diterima di sini), dan itu bekerja dengan sangat baik dan merupakan solusi yang sangat elegan.
Erik van der Neut

Itu juga tidak berhasil bagi saya karena itu mengubah perataan teks.
Iulian Onofrei

3

Lakukan sendiri. Xcode10, swift4,

Untuk desain UI terprogram

masukkan deskripsi gambar di sini

 lazy var buttonFilter : ButtonRightImageLeftTitle = {
    var button = ButtonRightImageLeftTitle()
    button.setTitle("Playfir", for: UIControl.State.normal)
    button.setImage(UIImage(named: "filter"), for: UIControl.State.normal)
    button.backgroundColor = UIColor.red
    button.contentHorizontalAlignment = .left
    button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
    return button
}()

Nilai inset tepi diterapkan pada persegi panjang untuk mengecilkan atau memperluas area yang ditunjukkan oleh persegi panjang itu. Biasanya, insets tepi digunakan selama tata letak tampilan untuk mengubah bingkai tampilan. Nilai positif menyebabkan frame menjadi inset (atau menyusut) dengan jumlah yang ditentukan. Nilai negatif menyebabkan frame menjadi awal (atau diperluas) dengan jumlah yang ditentukan.

class ButtonRightImageLeftTitle: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        guard imageView != nil else { return }

        imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: -((imageView?.bounds.width)! + 10), bottom: 0, right: 0 )

    }
}

untuk desain StoryBoard UI

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini


apakah ada cara untuk melakukannya dengan lebih elegan?
Zaporozhchenko Oleksandr


2

Mengambil jawaban @ Piotr dan membuatnya menjadi ekstensi Swift. Pastikan untuk mengatur gambar dan judul sebelum memanggil ini, sehingga ukuran tombol dengan benar.

extension UIButton {

/// Makes the ``imageView`` appear just to the right of the ``titleLabel``.
func alignImageRight() {
    if let titleLabel = self.titleLabel, imageView = self.imageView {
        // Force the label and image to resize.
        titleLabel.sizeToFit()
        imageView.sizeToFit()
        imageView.contentMode = .ScaleAspectFit

        // Set the insets so that the title appears to the left and the image appears to the right. 
        // Make the image appear slightly off the top/bottom edges of the button.
        self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -1 * imageView.frame.size.width,
            bottom: 0, right: imageView.frame.size.width)
        self.imageEdgeInsets = UIEdgeInsets(top: 4, left: titleLabel.frame.size.width,
            bottom: 4, right: -1 * titleLabel.frame.size.width)
    }
}

}


2

Opsi cepat yang melakukan apa yang Anda inginkan tanpa bermain dengan inset apa pun:

class RightImageButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let  textSize = titleLabel?.intrinsicContentSize(),
                imageSize = imageView?.intrinsicContentSize() {
            let wholeWidth = textSize.width + K.textImageGap + imageSize.width
            titleLabel?.frame = CGRect(
                x: round(bounds.width/2 - wholeWidth/2),
                y: 0,
                width: ceil(textSize.width),
                height: bounds.height)
            imageView?.frame = CGRect(
                x: round(bounds.width/2 + wholeWidth/2 - imageSize.width),
                y: RoundRetina(bounds.height/2 - imageSize.height/2),
                width: imageSize.width,
                height: imageSize.height)
        }
    }

    struct K {
        static let textImageGap: CGFloat = 5
    }

}

1

Solusi yang disebutkan di sini berhenti berfungsi, setelah saya mengaktifkan Tata Letak Otomatis . Saya harus membuat sendiri:

Subclass UIButton dan layoutSubviewsmetode override :

//
//  MIThemeButtonImageAtRight.m
//  Created by Lukasz Margielewski on 7/9/13.
//

#import "MIThemeButtonImageAtRight.h"

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets);

@implementation MIThemeButtonImageAtRight

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGRect contentFrame = CGRectByApplyingUIEdgeInsets(self.bounds, self.contentEdgeInsets);

    CGRect frameIcon = self.imageView.frame;
    CGRect frameText = self.titleLabel.frame;

    frameText.origin.x = CGRectGetMinX(contentFrame) + self.titleEdgeInsets.left;
    frameIcon.origin.x = CGRectGetMaxX(contentFrame) - CGRectGetWidth(frameIcon);

    self.imageView.frame = frameIcon;
    self.titleLabel.frame = frameText;
}

@end

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets){

    CGRect f = frame;

    f.origin.x += insets.left;
    f.size.width -= (insets.left + insets.right);
    f.origin.y += (insets.top);
    f.size.height -= (insets.top + insets.bottom);

    return f;

}

Hasil:

masukkan deskripsi gambar di sini


1

Swift 3.0 Migration solution diberikan oleh jasongregori

class ButtonIconRight: UIButton {
        override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
            var imageFrame = super.imageRect(forContentRect: contentRect)
           imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
        }

        override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
            var titleFrame = super.titleRect(forContentRect: contentRect)
            if (self.currentImage != nil) {
                titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
            }
            return titleFrame
        }

1

Saya memutuskan untuk tidak menggunakan tampilan gambar tombol standar karena solusi yang diusulkan untuk memindahkannya terasa dirusak. Ini memberi saya estetika yang diinginkan, dan intuitif untuk memposisikan ulang tombol dengan mengubah batasan:

extension UIButton {
    func addRightIcon(image: UIImage) {
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(imageView)

        let length = CGFloat(15)
        titleEdgeInsets.right += length

        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: self.titleLabel!.trailingAnchor, constant: 10),
            imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
            imageView.widthAnchor.constraint(equalToConstant: length),
            imageView.heightAnchor.constraint(equalToConstant: length)
        ])
    }
}

tombol dengan panah kanan


Ini tidak menanggapi ketukan, teks redup tetapi gambar tidak
Teddy K

0

Swift 3:

open override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.imageRect(forContentRect: contentRect)
    let  imageWidth = frame.size.width
    var titleRect = CGRect.zero
    titleRect.size = self.title(for: self.state)!.size(attributes: [NSFontAttributeName: self.titleLabel!.font])
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame
}

open override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.titleRect(forContentRect: contentRect)
    if let imageWidth = self.image(for: self.state)?.size.width {
        frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    }
    return frame
}

0

Bagaimana dengan Kendala? Tidak seperti semanticContentAttribute, mereka tidak mengubah semantik. Sesuatu seperti ini mungkin:

 button.rightAnchorconstraint(equalTo: button.rightAnchor).isActive = true

atau di Objective-C:

[button.imageView.rightAnchor constraintEqualToAnchor:button.rightAnchor].isActive = YES;

Peringatan: Belum teruji, iOS 9+


0

Untuk meluruskan gambar di dalam UIButton coba kode di bawah ini

btn.contentHorizontalAlignment = .right

Ini bukan pertanyaan penulis.
Mateusz

0

Setelah mencoba beberapa solusi dari seluruh internet, saya tidak mencapai persyaratan yang tepat. Jadi saya akhirnya menulis kode utilitas khusus. Posting untuk membantu seseorang di masa depan. Diuji pada swift 4.2

// This function should be called in/after viewDidAppear to let view render
    func addArrowImageToButton(button: UIButton, arrowImage:UIImage = #imageLiteral(resourceName: "my_image_name") ) {
        let btnSize:CGFloat = 32
        let imageView = UIImageView(image: arrowImage)
        let btnFrame = button.frame
        imageView.frame = CGRect(x: btnFrame.width-btnSize-8, y: btnFrame.height/2 - btnSize/2, width: btnSize, height: btnSize)
        button.addSubview(imageView)
        //Imageview on Top of View
        button.bringSubviewToFront(imageView)
    }

0

untuk masalah ini Anda dapat membuat UIView di dalam "label with UIImage view" dan mengatur kelas UIView sebagai UIControl dan membuat IBAction sebagai tuch up in side

masukkan deskripsi gambar di sini


0

Swift 4 & 5

Ubah arah gambar UIButton (RTL dan LTR)

extension UIButton {
    func changeDirection(){
       isArabic ? (self.contentHorizontalAlignment = .right) : (self.contentHorizontalAlignment = .left)
        // left-right margin 
        self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
        self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    }
}

Apa Utility?
Byron Coetsee

Saya baru saja menghapus Utilitas, Ini adalah kelas dalam kode saya di mana saya dapat memeriksa apakah bahasa yang dipilih adalah bahasa Arab atau Inggris
Rashid Latif

0

Xcode 11.4 Swift 5.2

Bagi siapa pun yang ingin meniru gaya tombol Kembali dengan chevron seperti ini:

masukkan deskripsi gambar di sini

import UIKit

class NextBarButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Set Title
        button.setTitle("Next", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Configure Symbol
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.right", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Put the Image on the right hand side of the button
        // Credit to liau-jian-jie for this part
        button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

        // Customise spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

Penerapan:

override func viewDidLoad() {
    super.viewDidLoad()
    let nextButton = NextBarButton(target: self, selector: #selector(nextTapped))
    navigationItem.rightBarButtonItem = nextButton
}

@objc func nextTapped() {
    // your code
}

0

Saya akhirnya membuat tombol kustom, yang memungkinkan pengaturan Gambar dari Inspektur. Di bawah ini adalah kode saya:

import UIKit

@IBDesignable
class CustomButton: UIButton {

    @IBInspectable var leftImage: UIImage? = nil
    @IBInspectable var gapPadding: CGFloat = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }

    func setup() {

        if(leftImage != nil) {
            let imageView = UIImageView(image: leftImage)
            imageView.translatesAutoresizingMaskIntoConstraints = false

            addSubview(imageView)

            let length = CGFloat(16)
            titleEdgeInsets.left += length

            NSLayoutConstraint.activate([
                imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: gapPadding),
                imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
                imageView.widthAnchor.constraint(equalToConstant: length),
                imageView.heightAnchor.constraint(equalToConstant: length)
            ])
        }
    }
}

Anda dapat menyesuaikan nilai Gap Padding dari Inspector untuk menyesuaikan jarak antara teks dan gambar.

PS: Menggunakan sebagian kode dari jawaban @ Mark Hennings

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.