จะสร้างเปอร์เซ็นต์ของความกว้างทั้งหมดโดยใช้การจัดวางอัตโนมัติได้อย่างไร


114

ฉันต้องการสร้างคอลัมน์ไดนามิกสามคอลัมน์แต่ละคอลัมน์มีเปอร์เซ็นต์คงที่ของความกว้างทั้งหมด ไม่ใช่ในสาม แต่เป็นค่าที่แตกต่างกัน ตัวอย่างเช่นภาพประกอบต่อไปนี้แสดงสามคอลัมน์: คอลัมน์แรกกว้าง 42% คอลัมน์ที่สองกว้าง 25% และคอลัมน์ที่สามกว้าง 33%

สำหรับ 600 พิกเซลข้ามวิวคอนโทรลเลอร์จะเป็น 252, 150 และ 198 พิกเซลตามลำดับ

อย่างไรก็ตามสำหรับขนาดการแสดงผลที่ตามมา (เช่น iPhone 4 แนวนอน (กว้าง 960) หรือแนวตั้งของ iPad 2 (กว้าง 768) ฉันต้องการให้เปอร์เซ็นต์สัมพัทธ์เท่ากัน (ไม่ใช่ความกว้างของพิกเซลที่ระบุไว้ด้านบน)

มีวิธีดำเนินการโดยใช้สตอรี่บอร์ด (เช่นไม่มีรหัส) หรือไม่? ฉันสามารถทำสิ่งนี้ได้อย่างง่ายดายในโค้ด แต่เป้าหมายของฉันคือใส่ตรรกะการแสดงผลนี้ลงใน Storyboard ให้มากที่สุด

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

คำตอบ:


205

ถ้าอย่างที่คุณพูดคุณรู้วิธีทำโค้ดคุณก็รู้วิธีทำในสตอรีบอร์ดแล้ว เป็นข้อ จำกัด ที่เหมือนกันทุกประการ แต่คุณกำลังสร้างด้วยภาพมากกว่าในรหัส

  1. เลือกทั้งข้อมูลพร็อพเพอร์ตี้และซูเปอร์วิว

  2. เลือกตัวแก้ไข -> ปักหมุด -> ความกว้างเท่า ๆ กันเพื่อ จำกัด ความกว้างให้เท่ากับความกว้างของซูเปอร์วิว (จริงๆแล้วกล่องโต้ตอบป๊อปอัป "ตรึง" ที่ด้านล่างของผืนผ้าใบจะทำงานได้ดีที่สุดที่นี่)

  3. แก้ไขข้อ จำกัด และตั้งค่าตัวคูณเป็นเศษส่วนที่ต้องการเช่น 0.42 และเช่นกันสำหรับมุมมองอื่น ๆ


9
ตรวจสอบให้แน่ใจว่ามุมมองที่คุณกำลัง จำกัด ปรากฏใน "รายการแรก" ของข้อ จำกัด ความกว้างเท่ากันไม่ใช่ความกว้างของมุมมองพิเศษมิฉะนั้นคุณกำลังสร้างความกว้างมุมมองย่อยของคุณเป็นทวีคูณของความกว้างของซูเปอร์วิว เมื่อการลากการควบคุมจากมุมมองย่อยไปยังมุมมองด้านบนเพื่อใช้ข้อ จำกัด ด้านความกว้างที่เท่ากันสิ่งเหล่านี้จะกลับรายการเสมอซึ่งดูเหมือนจะสวนทางกับฉัน
memmons

อ่า - โดย "ทำในโค้ด" ฉันหมายถึงบางอย่างมากกว่า "ด้วยตนเองโดยไม่มีข้อ จำกัด หรือการกำหนดค่าอัตโนมัติ"
Jeffrey Berthiaume

คำตอบที่ดี ฉันแปลกใจที่ IB ไม่ได้จัดเตรียมวิธีการแก้ไขข้อ จำกัด นี้
wcochran

ฉันพยายามใช้สิ่งนี้ใน UITableViewCell ของฉันและทุกอย่างเป็นสีเทา ฉันต้องฝังมุมมองทั้งหมดของฉันในมุมมองใหม่และเลือกความกว้างเท่ากันจากป้ายกำกับของฉันไปยังมุมมองใหม่นี้ หวังว่าจะช่วยได้
นาโน

6
ใหม่ใน Xcode7: หากคุณต้องการจัดแนวมุมมองให้เท่ากันให้ใช้ "Stack View" ใหม่
Bijan

15

เนื่องจาก Apple เปิดตัวUIStackViewทำให้งานง่ายขึ้นมาก

วิธีที่ 1: การใช้ Nib / StoryBoard:

คุณต้องเพิ่มมุมมองสามมุมมองในตัวสร้างอินเทอร์เฟซและฝังไว้ใน stackview

Xcode ► Editor ►ฝังใน► StackView

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

เลือก stackView และให้ข้อ จำกัด ด้วยความสูงนำหน้าต่อท้ายด้านบนและเท่ากันด้วย safeArea

คลิกเพื่อตรวจสอบคุณสมบัติและ ตั้งค่า StackView แนวนอนและการกระจายเพื่อเติมเต็มตามสัดส่วน

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

ให้ข้อ จำกัด ของมุมมองสามแบบโดยนำหน้า, ต่อท้าย, ด้านบน, ด้านล่างตามลำดับของด้านข้าง ใส่คำอธิบายภาพที่นี่

วิธีที่ 2: โดยทางโปรแกรม:

import UIKit
class StackViewProgramatically: UIViewController {
    var propotionalStackView: UIStackView!
    ///Initially defining three views
    let redView: UIView = {
        let view = UIView()//taking 42 % initially
        view.frame = CGRect(x: 0, y: 0, width: 42 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()//taking 42* initially
        view.frame = CGRect(x: 42 * UIScreen.main.bounds.width/100, y: 0, width: 25 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .green
        return view
    }()
    let blueView: UIView = {
        let view = UIView()//taking 33*initially
        view.frame = CGRect(x: 67 * UIScreen.main.bounds.width/100, y: 0, width: 33 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .blue
        return view
    }()

    ///Changing UIView frame to supports landscape mode.
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        DispatchQueue.main.async {
            self.redView.frame = CGRect(x: 0, y: 0, width: 42 * self.widthPercent, height: self.screenHeight)
            self.greenView.frame = CGRect(x: 42 * self.widthPercent, y: 0, width: 25 * self.widthPercent, height: self.screenHeight)
            self.blueView.frame = CGRect(x: 67 * self.widthPercent, y: 0, width: 33 * self.widthPercent, height: self.screenHeight)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        //Adding subViews to the stackView
        propotionalStackView = UIStackView()
        propotionalStackView.addSubview(redView)
        propotionalStackView.addSubview(greenView)
        propotionalStackView.addSubview(blueView)
        propotionalStackView.spacing = 0
        ///setting up stackView
        propotionalStackView.axis = .horizontal
        propotionalStackView.distribution = .fillProportionally
        propotionalStackView.alignment = .fill
        view.addSubview(propotionalStackView)
    }
}
//MARK: UIscreen helper extension
extension NSObject {

    var widthPercent: CGFloat {
        return UIScreen.main.bounds.width/100
    }

    var screenHeight: CGFloat {
        return UIScreen.main.bounds.height
    }
}

เอาท์พุท:

ทำงานร่วมกับแนวนอนและแนวตั้ง

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

โครงการสาธิต - https://github.com/janeshsutharios/UIStackView-with-constraints

https://developer.apple.com/videos/play/wwdc2015/218/


4

ฉันคิดว่าสิ่งนี้สามารถอธิบายได้อย่างละเอียดมากขึ้นเพื่อให้สามารถนำไปใช้กับจำนวนการดูที่ต้องการรูปแบบเปอร์เซ็นต์คงที่ภายใน superview ได้ง่ายขึ้น

มุมมองซ้ายสุด

  • จอดทอดสมอ SuperView.Leading
  • กำหนดเปอร์เซ็นต์คงที่เป็นตัวคูณใน SuperView.Height

มุมมองระดับกลาง

  • กำหนดเปอร์เซ็นต์คงที่เป็นตัวคูณใน SuperView.Height
  • ปักหมุดleftไว้ทางขวาของเพื่อนบ้าน

มุมมองด้านขวาสุด

  • ไม่กำหนดเปอร์เซ็นต์คงที่ (เป็นส่วนที่เหลือของมุมมองที่มีอยู่)
  • ปักหมุดleftไว้ทางขวาของเพื่อนบ้าน
  • ตรึงrightไว้ที่SuperView.Trailing

มุมมองทั้งหมด

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