bilah navigasi kutu gambar-tombol bilah kanan iOS 11

101

Kode ini berfungsi dengan baik di ios10. saya mendapatkan label saya dan tombol gambar yang merupakan profil foto pengguna, lingkaran melingkar .. ok. tetapi ketika menjalankan simulator xcode 9 ios11 saya mendapatkannya keluar. bingkai tombol harus 32x32, ketika memeriksa sim dan mendapatkan tampilan dan memberitahu xcode untuk menggambarkan tampilan saya mendapatkan keluaran sebagai 170x32 atau sesuatu seperti itu.

inilah kode saya.

let labelbutton = UIButton( type: .system)
    labelbutton.addTarget(self, action:#selector(self.toLogin(_:)), for: .touchUpInside)
    labelbutton.setTitleColor(UIColor.white, for: .normal)
    labelbutton.contentHorizontalAlignment = .right
    labelbutton.titleLabel?.font = UIFont.systemFont(ofSize: 18.00)



    let button = UIButton(type: .custom)
     button.addTarget(self, action:#selector(self.toLogin(_:)), for: .touchUpInside)
     button.frame = CGRect(x: 0, y: 0, width: 32, height: 32)
     button.setTitleColor(UIColor.white, for: .normal)
     button.setTitleColor(UIColor.white, for: .highlighted)


    var buttomItem : UIBarButtonItem = UIBarButtonItem()
    buttomItem.customView = button
    buttomItem.target = self
    buttomItem.action = "ToLogin"

    var labelItem : UIBarButtonItem = UIBarButtonItem()
    labelItem.customView = labelbutton
    labelItem.target = self
    labelItem.action = "ToLogin"


    if let user = PFUser.current() {
        print("LOGIN : checkiando si existe usuario ")
            labelbutton.setTitle(USERNAME, for: UIControlState.normal)
            labelbutton.sizeToFit()

        if(user["profile_photo_url"] != nil) {
            print(" ENCONTRO PROFILE PHOTO URL NOT NIL Y ES \(user["profile_photo_url"])")
            let photoURL = user["profile_photo_url"] as! String
            let a = LoginService.sharedInstance
            a.downloadImage(url: photoURL, complete: { (complete) in

                if (complete) {

                    button.setImage(LoginService.sharedInstance.profile_photo! , for: UIControlState.normal)

                    button.layer.cornerRadius = 0.5 * button.bounds.size.width
                   // button.imageView!.contentMode = .scaleAspectFit
                   // button.imageView!.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
                    //button.imageView!.contentMode = .scaleAspectFit
                    //button.imageView!.clipsToBounds = true
                    //button.imageView!.layer.cornerRadius = 60
                    button.clipsToBounds = true
                    self.NavigationItem.rightBarButtonItems = [buttomItem,labelItem]
                }


            })
        } else {
                self.NavigationItem.rightBarButtonItem = labelItem

        }
            print(" EL FRAME DEL BUTTON ES \(button.frame)")

    } else {

        labelbutton.setTitle("Login", for: UIControlState.normal)
        labelbutton.sizeToFit()
        self.NavigationItem.rightBarButtonItem = labelItem

    }

masukkan deskripsi gambar di sini

lorenzo gonzalez
sumber
Apakah Anda menggunakan tampilan tumpukan di bilah navigasi?
Vlad Khambir
@ V.Khambir Nop ...: /
lorenzo gonzalez
apakah laporan bug ini ada di mana saja?
Edu
iOS 11 menggunakan AutoLayout untuk mengatur tata letak item navigasi. Jika Anda perlu menggeser bagian UIButtondalam UIBarButtonItem, gunakanbutton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: -20)
onmyway133

Jawaban:

188

Alasan

Masalahnya muncul karena dari ios 11 UIBarButtonItemmenggunakan autolayout alih-alih berurusan dengan bingkai.

Larutan

Anda harus menambahkan batasan lebar untuk tombol gambar ini jika Anda menggunakan Xcode 9.

 button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
 button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true

PS

buttontidak UIBarButtonItem, itu ada UIButtondi dalam UIBarButtonItem. Anda harus menyetel batasan bukan untuk UIBarButtonItem, tetapi untuk elemen di dalamnya.

Vlad Khambir
sumber
3
@ V.Khambir sekarang saya mendapatkan masalah ini. Tetapi dengan solusi yang sama dengan xcode 9, dan jika saya menjalankan di perangkat ios 1 itu baik-baik saja .. Tetapi jika saya menjalankan di perangkat versi ios 10 .. gambar tombol bar saya sama sekali tidak ditampilkan. Bagaimana saya bisa memperbaiki semua versi untuk ini. Saya memeriksa perangkat dari kedua ios 11, ios 10. Hanya menunjukkan yang bagus di versi ios 1. di iOS 10, gambar sama sekali tidak ditampilkan
david
@spikesa, ini seharusnya bekerja pada kedua versi iOS, mungkin Anda telah menyetel batasan yang salah.
Vlad Khambir
@ V.Khambir Nilai tipe 'UIBarButtonItem' tidak memiliki anggota 'widthAnchor' di Xcode 9 di dalam jika #available (iOS 11.0, *) bersyarat?
Ryan Brodie
1
@jped apakah Anda menemukan solusi untuk ini? Itu tidak berfungsi untuk saya juga di iOS 10 dengan Xcode 9
swalkner
1
Bagus. Harus menyukai perubahan yang merusak ini. Apakah Apple telah mendokumentasikan daftar jenis perubahan ini di halaman atau catatan rilis di suatu tempat?
GONeale
53

Terima kasih semua telah berkontribusi! kalian benar !. untuk xcode9 ios11 Anda perlu memberi batasan.

 let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
 let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
 heightConstraint.isActive = true
 widthConstraint.isActive = true
lorenzo gonzalez
sumber
1
Ini bekerja untuk saya juga, tetapi adakah yang bisa menjelaskan mengapa ini diperlukan untuk iOS 11 padahal belum pernah sebelumnya?
stonedauwg
9
UINavigationBar sekarang mengatur tampilan subviewnya menggunakan Auto Layout
mangerlahn
2
Jangan membuat kesalahan yang sama seperti yang saya lakukan: Saya mematikan translatesAutoresizingMaskIntoConstraintsdan kemudian menemukan bahwa iOS 9 benar-benar rusak (tetapi tampak baik-baik saja di iOS 10 dan 11)
xaphod
2
Value of type 'UIBarButtonItem' has no member 'widthAnchor'di Xcode 9 di dalam if #available(iOS 11.0, *)bersyarat?
Ryan Brodie
@ lorenzo-gonzalez Bagaimana Anda membuatnya bulat? Saya terjebak dalam hal ini.
Alessandro Lucarini
18

Kode Objective C sudah usang sekarang. Tetapi bagi pengguna yang harus membangun / memelihara proyek Objective C di iOS 11 telah mengikuti terjemahan dari Swift (jawaban Karoly Nyisztor) ke Objective C membantu.

//  UIView+Navbar.h

#import <UIKit/UIKit.h>

@interface UIView (Navbar)

- (void)applyNavBarConstraints:(CGFloat)width height:(CGFloat)height;

@end

//----------

//  UIView+Navbar.m

#import "UIView+Navbar.h"

@implementation UIView (Navbar)

- (void)applyNavBarConstraints:(CGFloat)width height:(CGFloat)height
{
    if (width == 0 || height == 0) {
        return;
    }

    NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:height];
    NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:width];
    [heightConstraint setActive:TRUE];
    [widthConstraint setActive:TRUE];
}

//----------

// Usage :-
[button applyNavBarConstraints:33 height:33];
SHS
sumber
Keren. Sebenarnya, saya membutuhkan versi Objective-C juga. Btw, Xcode 9 terus mengubah ukuran item navbar di storyboard secara acak. Saya harus memeriksa ulang setiap kali sebelum mendorong perubahan saya. Semoga ini segera diperbaiki.
Karoly Nyisztor
Anda adalah pahlawan saya, karena saya perlu memperbaiki proyek lama dengan tujuan-c.
Marosdee Uma
18

Nah, yang baru barButtonItemmenggunakan autolayout alih-alih berurusan dengan bingkai.

Gambar yang Anda tambahkan ke tombol lebih besar dari ukuran tombol itu sendiri. Itulah mengapa tombol itu sendiri diperpanjang ke ukuran gambar. Anda harus mengubah ukuran gambar agar sesuai dengan ukuran tombol yang dibutuhkan, sebelum menambahkannya ke tombol.

Ahmad Farrag
sumber
14

Saya menulis ekstensi kecil untuk mengatur batasan pada item navbar:

import UIKit

extension UIView {
    func applyNavBarConstraints(size: (width: CGFloat, height: CGFloat)) {
    let widthConstraint = self.widthAnchor.constraint(equalToConstant: size.width)
    let heightConstraint = self.heightAnchor.constraint(equalToConstant: size.height)
    heightConstraint.isActive = true
    widthConstraint.isActive = true
  }
}

// Usage
button.applyNavBarConstraints(size: (width: 33, height: 33))
Karoly Nyisztor
sumber
Ide yang hebat! Penerapan yang satu ini UIButtonbekerja dengan sangat baik.
Alessandro Ornano
12

Saya melakukan ini secara objektif menggunakan baris berikut:

NSLayoutConstraint * widthConstraint = [customButton.widthAnchor constraintEqualToConstant:40];
NSLayoutConstraint * HeightConstraint =[customButton.heightAnchor constraintEqualToConstant:40];
[widthConstraint setActive:YES];
[HeightConstraint setActive:YES];

UIBarButtonItem* customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.leftBarButtonItem = customBarButtonItem;

Terima kasih Selamat coding !!

Aleem
sumber
7

Apa yang saya lakukan?

Di aplikasi saya, saya menambahkan gambar profil di navigationBar di item rightBarButton. sebelum iOS 11 itu berfungsi dengan baik dan ditampilkan dengan benar tetapi ketika diperbarui ke iOS 11 kemudian mengubah perilaku seperti pukulan

masukkan deskripsi gambar di sini

Jadi saya menambahkan UIViewitem tombol kanan dan menetapkan UIButtonsebagai subview dari UIView? Seperti di bawah ini,

masukkan deskripsi gambar di sini

Dan saya menetapkan batasan tinggi dan lebar UIButton.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Dan masalah saya terpecahkan. Jangan lupa untuk mengatur UIViewwarna background menjadi warna yang jelas .

CATATAN: Jika tombol Anda tidak berfungsi maka periksa UIView'stinggi badan Anda mungkin 0 di sini Anda harus mengubah tinggi 0 menjadi 44 atau apa pun yang Anda inginkan. Dan juga lakukan clipToBound = true, Sekarang Anda dapat mengatur posisi tombol Anda dan itu akan bekerja dengan baik.

iPatel
sumber
Ini berfungsi, namun tombol berhenti berfungsi saat Anda menambahkannya dalam tampilan. Ada tips?
eonist
@GitSync Periksa tinggi tampilan Anda itu akan menjadi 0 ubah menjadi 44 atau apapun yang Anda inginkan dan buat clipToBound = true dan kemudian tombol set.
iPatel
1
Wow. berhasil! Kiat pro: gunakan aset .pdf alih-alih .png
eonist
apakah tampilan kontainer diperlukan? Tidak bisakah saya menggunakan UIButton secara langsung?
igrek
5

Mengubah widthAnchor/ heightAnchorhanya akan berfungsi di perangkat iOS 11+. Untuk perangkat iOS 10 Anda harus menggunakan cara klasik untuk mengubah frame secara manual. Masalahnya adalah tidak ada dari dua pendekatan yang berfungsi untuk kedua versi, jadi Anda benar-benar perlu bergantian secara terprogram bergantung pada versi runtime, seperti di bawah ini:

if #available(iOS 11.0, *)
{
   button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
   button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true
}else
{
   var frame = button.frame
   frame.size.width = 32.0
   frame.size.height = 32.0
   button.frame = frame
}
Malloc
sumber
1
Terima kasih atas tip iOS 10! Saya memiliki perbaikan iOS 11 yang berfungsi tetapi tidak dapat mengetahuinya untuk iOS 10.
Clifton Labrum
3

Meskipun iOS 11 menggunakan Autolayout untuk bilah navigasi, dimungkinkan untuk membuatnya berfungsi secara tradisional dengan mengatur bingkai. Ini kode saya yang berfungsi untuk ios11 dan ios10 atau lebih lama:

func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem {
    let container = UIView(frame: rect)
    container.addSubview(view)
    view.frame = rect
    return UIBarButtonItem(customView: container)
}

dan berikut adalah bagaimana item bar disusun:

    let btn = UIButton()
    btn.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
    btn.tintColor = tint
    btn.imageView?.contentMode = .scaleAspectFit
    let barItem = barItemWithView(view: btn, rect: CGRect(x: 0, y: 0, width: 22, height: 22))
    return barItem
Leszek Zarna
sumber
3

Menempatkan batasan secara terprogram bekerja untuk saya untuk pengguna yang menjalankan iOS 11.X. Namun, tombol bar masih meregang untuk pengguna yang menjalankan iOS 10.X. Saya kira pengulas AppStore menjalankan iOS 11.X sehingga tidak dapat mengidentifikasi masalah saya sehingga aplikasi saya siap untuk dijual dan diunggah ..

Solusi saya adalah mengubah dimensi gambar saya menjadi 30x30 di perangkat lunak lain (dimensi gambar sebelumnya 120x120).

Erik Nguyen
sumber
1
Karena navigationbar di ios10 melakukan pengaturan otomatis dan ios11 adalah autolayout, Anda perlu menggunakan if #available (iOS 11, *) {}
Paulo Sigales
Saya akan melalui perubahan baru dan saya menemukan pertanyaan ini, tetapi jawaban ini saya kira pengembang harus menggunakan
Shobhakar Tiwari
Jawaban yang bagus dan sederhana. Terima kasih. Tidak ada lagi yang berhasil dan itu membuatku gila.
Brittany
0

Saya juga berhasil menerapkan intrinsicContentSizeuntuk mengembalikan ukuran yang sesuai untuk setiap subkelas UIView khusus yang ingin saya gunakan sebagai customView.

Chris
sumber
0

Saya telah membuat item tombol bar dan kemudian menambahkannya ke bar navigasi.

    private var addItem: UIBarButtonItem = {
        let addImage = UIImage(named: "add")
        let addButton = UIButton(type: UIButton.ButtonType.custom)
        addButton.setBackgroundImage(addImage, for: UIControl.State())
        addButton.frame = CGRect(x: 0, y: 0, width: (addImage?.size.width)!, height: (addImage?.size.height)!)
        let addItem = UIBarButtonItem(customView: addButton)
        return addItem
    }()

 private var contactsItem: UIBarButtonItem = {
        let contactsImage = UIImage(named: "contacts")
        let contactsButton = UIButton(type: UIButton.ButtonType.custom)
        contactsButton.setBackgroundImage(contactsImage, for: UIControl.State())
        contactsButton.frame = CGRect(x: 0, y: 0, width: (contactsImage?.size.width)!, height: (contactsImage?.size.height)!)
        let contactsItem = UIBarButtonItem(customView: contactsButton)
        return contactsItem
    }()

Dalam viewDidLoad ()

let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
        spacerBarButtonItem.width = 11
        navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]

Di sini saya memiliki gambar 28x28.

vinny
sumber