แถบนำทางแถบด้านขวาข้อผิดพลาดปุ่มรูปภาพ 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

    }

ใส่คำอธิบายภาพที่นี่


คุณใช้มุมมองสแต็กในแถบนำทางหรือไม่
Vlad Khambir

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

รายงานข้อผิดพลาดนี้อยู่ที่ใด
Edu

iOS 11 ใช้ AutoLayout เพื่อจัดวางรายการการนำทาง ในกรณีที่คุณต้องการเปลี่ยนUIButtonด้านในUIBarButtonItemให้ใช้button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: -20)
onmyway133

คำตอบ:


188

เหตุผล

ปัญหาปรากฏขึ้นเนื่องจากจาก ios 11 UIBarButtonItemใช้การจัดวางอัตโนมัติแทนการจัดการกับเฟรม

สารละลาย

คุณควรเพิ่มข้อ จำกัด ด้านความกว้างสำหรับปุ่มรูปภาพนี้หากคุณใช้ Xcode 9

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

ปล

buttonไม่ได้UIBarButtonItemมันเป็นเรื่องภายในUIButton UIBarButtonItemคุณไม่ควรตั้งค่าข้อ จำกัดUIBarButtonItemแต่สำหรับองค์ประกอบภายในนั้น


3
@ V.Khambir ตอนนี้ฉันได้รับปัญหานี้ แต่ด้วยวิธีแก้ปัญหาเดียวกันนี้กับ xcode 9 และถ้าฉันรันในอุปกรณ์ ios 1 ก็ใช้ได้ แต่ถ้าฉันรันในอุปกรณ์เวอร์ชัน ios 10 .. รูปภาพปุ่มแถบของฉันไม่แสดงเลย ฉันจะแก้ไขทุกเวอร์ชันสำหรับสิ่งนี้ได้อย่างไร ฉันเช็คอินอุปกรณ์ของทั้ง ios 11, ios 10 แสดงได้ดีในเวอร์ชัน ios 1 เท่านั้น ใน ios 10 ภาพไม่แสดงเลย
david

@spikesa ควรใช้กับ iOS ทั้งสองเวอร์ชันอาจเป็นไปได้ว่าคุณตั้งค่าข้อ จำกัด ไม่ถูกต้อง
Vlad Khambir

@ V.Khambir ค่าของประเภท 'UIBarButtonItem' ไม่มีสมาชิก 'widthAnchor' ใน Xcode 9 ภายใน if #available (iOS 11.0, *) conditional?
Ryan Brodie

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 ได้จัดวางมุมมองย่อยโดยใช้ Auto Layout แล้ว
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, *)เงื่อนไข?
Ryan Brodie

@ lorenzo-gonzalez คุณทำให้มันกลมได้อย่างไร? ฉันติดอยู่กับเรื่องนี้
Alessandro Lucarini

18

รหัส Objective C ล้าสมัยแล้ว แต่สำหรับผู้ใช้ที่ต้องสร้าง / ดูแลโปรเจ็กต์ Objective C ใน iOS 11 จะมีการแปลตามจาก Swift (คำตอบของ Karoly Nyisztor) เป็น 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 จะทำการปรับขนาดรายการ navbar แบบสุ่มในกระดานเรื่องราว ฉันต้องตรวจสอบอีกครั้งทุกครั้งก่อนที่จะทำการเปลี่ยนแปลง หวังว่าจะได้รับการแก้ไขในไม่ช้า
Karoly Nyisztor

คุณเป็นฮีโร่ของฉันเพราะฉันต้องการ refactor โครงการเก่าด้วยวัตถุประสงค์ -c
Marosdee Uma

18

ใหม่barButtonItemใช้การจัดวางอัตโนมัติแทนการจัดการกับเฟรม

รูปภาพที่คุณเพิ่มลงในปุ่มมีขนาดใหญ่กว่าขนาดของปุ่มเอง นั่นเป็นเหตุผลว่าทำไมปุ่มจึงยืดออกไปตามขนาดของภาพ คุณต้องปรับขนาดรูปภาพให้ตรงกับขนาดของปุ่มที่ต้องการก่อนจึงจะเพิ่มลงในปุ่มได้


14

ฉันเขียนส่วนขยายเล็ก ๆ สำหรับตั้งค่าข้อ จำกัด ในรายการ 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))

ความคิดที่ดี! ใช้อันนี้ได้UIButtonผลดีมาก
Alessandro Ornano

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;

ขอบคุณ Happy coding !!


7

ฉันทำอะไรลงไป?

ในแอพของฉันฉันเพิ่มรูปโปรไฟล์บน navigationBar ที่รายการ rightBarButton ก่อน iOS 11 มันใช้งานได้ดีและแสดงผลอย่างถูกต้อง แต่เมื่ออัปเดตเป็น iOS 11 แล้วจะเปลี่ยนพฤติกรรมเช่นระเบิด

ใส่คำอธิบายภาพที่นี่

ดังนั้นฉันจึงเพิ่มUIViewในรายการปุ่มขวาและตั้งUIButtonเป็นมุมมองย่อยของUIView? เช่นด้านล่าง

ใส่คำอธิบายภาพที่นี่

UIButtonและเราจะตั้งความสูงและความกว้างของข้อ จำกัด

ใส่คำอธิบายภาพที่นี่ ใส่คำอธิบายภาพที่นี่

และปัญหาของฉันได้รับการแก้ไข อย่าลืมตั้งค่าUIViewสีพื้นหลังเป็นสีใส

หมายเหตุ:หากปุ่มของคุณไม่ทำงานให้ตรวจสอบUIView'sความสูงของคุณว่าอาจเป็น0 ที่นี่คุณควรเปลี่ยนความสูง0ถึง44หรืออะไรก็ได้ที่คุณต้องการ และทำเช่นclipToBound = trueนี้ตอนนี้คุณสามารถกำหนดตำแหน่งของปุ่มของคุณและมันจะทำงานได้ดี


วิธีนี้ได้ผลอย่างไรก็ตามปุ่มจะหยุดทำงานเมื่อคุณเพิ่มเข้าไปในมุมมอง เคล็ดลับใด ๆ
eonist

@GitSync ตรวจสอบความสูงของมุมมองของคุณมันจะเป็น 0 เปลี่ยนเป็น 44 หรืออะไรก็ได้ที่คุณต้องการและทำให้ clipToBound = true แล้วตั้งค่าปุ่ม
iPatel

1
ว้าว. ได้ผล! เคล็ดลับสำหรับมือโปร: ใช้เนื้อหา. pdf แทน. png
eonist

มุมมองคอนเทนเนอร์จำเป็นไหม ฉันใช้ UIButton โดยตรงไม่ได้หรือ
igrek

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
Clifton Labrum

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
เนื่องจาก navigationbar ใน ios10 มีการปรับขนาดอัตโนมัติและ ios11 เป็นแบบอัตโนมัติคุณจึงต้องจัดการกับ if #available (iOS 11, *) {}
Paulo Sigales

ฉันกำลังจะผ่านการเปลี่ยนแปลงใหม่และพบคำถามนี้ แต่คำตอบนี้ฉันเดาว่านักพัฒนาควรใช้
Shobhakar Tiwari

คำตอบที่ดีและเรียบง่าย ขอบคุณ. ไม่มีอะไรใช้ได้ผลและมันทำให้ฉันแทบคลั่ง
Brittany

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.