навігаційна панель справа-баріть помилка кнопки зображення iOS 11


101

Цей код працює нормально в ios10. я отримую мітку та кнопку зображення, яка є профілем фотографії користувача, кругла кругла .. ОК. але при запуску симулятора xcode 9 ios11 я отримую його розтягнутий. Рамка кнопки повинна бути 32x32, коли перевіряється на сим і отримує перегляд і каже xcode для опису подання, я отримую вихід як 170x32 або щось подібне.

ось мій код.

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

    }

введіть тут опис зображення


Чи використовували ви вигляд стека на панелі навігації?
Влад Хамбір

@ V.Khambir Nop ...: /
lorenzo gonzalez

це повідомлення про помилку де-небудь?
Еду

iOS 11 використовує функцію AutoLayout для компонування елементів навігації. Якщо вам потрібно зрушити UIButtonвнутрішню UIBarButtonItembutton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: -20)
частину

Відповіді:


188

Причина

Проблема з'являється через те, що з ios 11 UIBarButtonItemвикористовується авторозкладка замість роботи з кадрами.

Рішення

Ви повинні додати обмеження ширини для цієї кнопки зображення, якщо ви використовуєте Xcode 9.

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

PS

buttonні UIBarButtonItem, це UIButtonвсередині UIBarButtonItem. Ви повинні встановлювати обмеження не для UIBarButtonItem, а для елементів всередині нього.


3
@ В.Камбір зараз я отримую це питання. Але з цим самим рішенням з xcode 9, і якщо я запускаю на пристрої ios 1 його нормально ... Але якщо я запускаю на пристрої версії ios 10, зображення моєї панелі не відображаються взагалі. Як я можу виправити всі версії для цього. Я перевірив у пристрої обох ios 11, ios 10. Тільки добре показано у версії ios 1. у ios 10, зображення зовсім не відображається
David

@spikesa, він повинен працювати в обох версіях iOS, ймовірно, ви встановили неправильні обмеження.
Влад Хамбір

@ V.Khambir Значення типу "UIBarButtonItem" не має члена "widthAnchor" у Xcode 9 всередині, якщо #available (iOS 11.0, *) умовне?
Райан Броді

1
@jped Ви знайшли рішення для цього? Він не працює для мене також на iOS 10 з Xcode 9
swalkner

1
Чудово. Треба любити ці переломні зміни. Чи Apple задокументувала перелік таких типів змін на сторінці чи десь випустила нотатки?
GONeale

53

Дякуємо всім за ваш внесок! ви праві, хлопці! для xcode9 ios11 потрібно поставити обмеження.

 let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
 let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
 heightConstraint.isActive = true
 widthConstraint.isActive = true

1
Це працювало і для мене, але чи може хтось пояснити, чому це потрібно для iOS 11, коли цього ніколи не було?
stonedauwg

9
Тепер UINavigationBar розміщує свої підгляди за допомогою автоматичного макета
mangerlahn

2
Не робіть тієї самої помилки, яку я робив: я вимкнувся, translatesAutoresizingMaskIntoConstraintsа потім пізніше з'ясував, що повністю зламав iOS 9 (але добре виглядав на iOS 10 і 11)
xaphod

2
Value of type 'UIBarButtonItem' has no member 'widthAnchor'в Xcode 9 всередині if #available(iOS 11.0, *)умовного?
Райан Броді

@ lorenzo-gonzalez Як ти обійшов? Я застряг у цьому.
Алессандро Лукаріні

18

Об'єктивний код C зараз застарілий. Але для користувача, який повинен будувати / підтримувати проекти Objective C в iOS 11, корисний наступний переклад з Swift (відповідь Каролі Нійштор) на Objective C.

//  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];

Класно. Власне, мені потрібна була і версія Objective-C. Btw, Xcode 9 зберігає випадкову зміну елементів навбарного аркуша. Я маю щоразу двічі перевіряти, перш ніж натискати на зміни. Сподіваюся, що це врешті-решт буде виправлено.
Karoly Nyisztor

ти мій герой, тому що мені потрібно рефактор старого проекту з метою-c.
Marosdee Uma

18

Ну, нове barButtonItemвикористовує автоматичний розклад замість роботи з кадрами.

Зображення, яке ви додавали до кнопки, більше, ніж розмір самої кнопки. Ось чому сама кнопка розтягнулася до розміру зображення. Перед тим, як додати його до кнопки, потрібно змінити розмір зображення, щоб він відповідав необхідному розміру кнопки.


14

Я написав крихітне розширення для встановлення обмежень на елементах навбар:

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))

Чудова ідея! Застосував цю UIButtonроботу дуже добре.
Алессандро Орнано

12

Я зробив це об'єктивно, використовуючи наступні рядки:

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;

Дякую Щасливе кодування !!


7

Що я зробив?

У своєму додатку я додав зображення профілю на навігаційному барі в пункті rightBarButton. до iOS 11 він працював добре і відображався належним чином, але коли оновлено до iOS 11, то змініть поведінку, як удар

введіть тут опис зображення

Тож я додав UIViewу праву кнопку пункт і встановив UIButtonяк підвід UIView? Як і нижче,

введіть тут опис зображення

І я встановлюю обмеження по висоті та ширині UIButton.

введіть тут опис зображення введіть тут опис зображення

І моя проблема вирішена. Не забудьте встановити UIViewколір тла як чіткий колір.

ПРИМІТКА. Якщо ваша кнопка не працює, то перевірте, чи UIView'sможе бути висота 0, тут слід змінити висоту 0 на 44 або все, що завгодно. А також зробіть clipToBound = true: Тепер ви можете встановити положення вашої кнопки, і це буде добре.


Це працює, однак кнопка перестає працювати, коли ви додасте її у подання. Якісь поради?
еоніст

@GitSync Перевірте висоту вашого перегляду, це буде 0, змініть його на 44 або все, що завгодно, і зробіть clipToBound = true, а потім встановіть кнопку.
iPatel

1
Ого. працює! Підказка: використовуйте .pdf активи замість .png
eonist

чи потрібен перегляд контейнера? Не можу я просто використовувати UIButton безпосередньо?
ігрик

5

Зміна widthAnchor/ heightAnchorпрацюватиме лише на пристроях iOS 11+. Для пристроїв iOS 10 вам потрібно пройти класичний спосіб ручної зміни кадрів. Вся справа в тому, що жоден з двох підходів не працює для обох версій, тому вам абсолютно потрібно програмувати чергування залежно від версії виконання, як нижче:

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
}

1
Дякуємо за підказку для iOS 10! У мене виправлення iOS 11 працювало, але не вдалося розібратися в iOS 10.
Кліфтон Лабрум

3

Навіть незважаючи на те, що iOS 11 використовує функцію Autolayout для панелі навігації, можливо, вона працює для традиційного встановлення кадрів. Ось мій код, який працює для ios11 та ios10 або новіших версій:

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

і ось як складається елемент рядка:

    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

3

Встановлення обмежень програмно працювало на мене для користувачів, які працюють на iOS 11.X. Однак кнопка смужки все ж була розтягнута для користувачів, які працюють на iOS 10.X. Я думаю, що рецензенти AppStore працювали під iOS 11.X, тому не вдалося визначити мою проблему, тому моє додаток було готове до продажу та завантажено ..

Моє рішення - просто змінити розміри мого зображення на 30x30 в іншому програмному забезпеченні (попередній розмір зображення - 120x120).


1
Оскільки панель навігації в ios10 є автоматизованою, а ios11 є автоматичною розгорткою, вам потрібно впоратися, якщо #available (iOS 11, *) {}
Пауло Сігалес

Я переглядав нові зміни, і я знайшов це питання, але цю відповідь я думаю, розробник повинен використовувати
Shobhakar Tiwari

Чудова, проста відповідь. Дякую. Ніщо більше не працювало, і це зводило мене з розуму.
Бретань

0

Я також мав успіх, реалізуючи intrinsicContentSizeповернути відповідний розмір для будь-якого користувацького підкласу UIView, який я маю намір використовувати як customView.


0

Я створив елемент кнопки панелі, а потім додав її на панель навігації.

    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
    }()

У viewDidLoad ()

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

Тут у мене є зображення розміром 28x28.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.