Jak utworzyć procent całkowitej szerokości za pomocą automatycznego układu?

114

Muszę utworzyć trzy dynamiczne kolumny, każda ze stałym procentem całkowitej szerokości. Nie trzecie, ale różne wartości. Na przykład na poniższej ilustracji przedstawiono trzy kolumny: pierwsza ma 42% szerokości, druga 25%, a trzecia 33% szerokości.

W przypadku 600 pikseli w kontrolerze widoku będzie to odpowiednio 252, 150 i 198 pikseli.

Jednak dla wszystkich kolejnych rozmiarów wyświetlacza (np. IPhone 4 poziomy (szerokość 960) lub iPad 2 pionowy (szerokość 768) chciałbym, aby względne wartości procentowe były takie same (nie podane powyżej szerokości pikseli).

Czy istnieje sposób, aby to zrobić za pomocą Storyboardów (tj. Bez kodu)? Mogę to łatwo zrobić w kodzie, ale moim celem jest umieszczenie jak największej ilości tej logiki wyświetlania w Storyboard.

wprowadź opis obrazu tutaj

Jeffrey Berthiaume
źródło

Odpowiedzi:

205

Jeśli, jak mówisz, wiesz, jak to zrobić w kodzie, to już wiesz, jak to zrobić w scenorysie. To dokładnie te same ograniczenia, ale tworzysz je wizualnie, a nie w kodzie.

  1. Wybierz widok i jego nadzór.

  2. Wybierz Edytor -> Przypnij -> Szerokości Równie, aby ograniczyć szerokość tak, aby była równa szerokości superviewu (w rzeczywistości najlepiej sprawdza się wyskakujące okienko wyskakujące na dole obszaru roboczego).

  3. Edytuj ograniczenie i ustaw Mnożnik na żądany ułamek, np. 0,42. I to samo dotyczy innych poglądów.

matowe
źródło
9
Upewnij się, że widok, który ograniczasz, pojawia się w „pierwszym elemencie” ograniczenia Równe szerokości, a nie w szerokości superviewu, w przeciwnym razie szerokość podglądu podrzędnego będzie wielokrotnością szerokości superviewu. Podczas przeciągania kontrolki z widoku podrzędnego do podglądu superwizji w celu zastosowania ograniczenia równej szerokości są one zawsze odwracane, co wydaje mi się sprzeczne z intuicją.
memmons
Ach - przez „robienie tego w kodzie” miałem na myśli coś bardziej jak „ręcznie, bez ograniczeń i autoukładu”.
Jeffrey Berthiaume
Niezła odpowiedź. Jestem zaskoczony, że IB nie daje sposobu na zrobienie tego bez edycji ograniczenia.
wcochran
Próbowałem zastosować to w mojej UITableViewCell i wszystko było wyszarzone. Musiałem osadzić wszystkie moje widoki w nowym widoku i wybrać Równą szerokość z mojej etykiety do tego nowego widoku. Mam nadzieję, że to pomoże.
nano
6
Nowość w Xcode7: jeśli chcesz równo wyrównać widoki, użyj nowego „widoku stosu”.
Bijan
15

Ponieważ Apple wprowadza UIStackView , praca jest znacznie łatwiejsza.

Metoda 1: Używanie Nib / StoryBoard:

Musisz po prostu dodać trzy widoki w kreatorze interfejsów i osadzić je w widoku stosu

Xcode ► Editor ► Osadź w ► StackView

wprowadź opis obrazu tutaj

Wybierz stackView i podaj ograniczenie z wiodącym, końcowym, górną i równą wysokością za pomocą safeArea

Kliknij, aby obszar inspektora atrybutów i ustaw StackView w poziomie i rozkładzie, aby wypełnić proporcjonalnie

[ wprowadź opis obrazu tutaj3

Podaj ograniczenie trzech widoków z początkowym, końcowym, górnym, dolnym i odpowiednimi bokami. wprowadź opis obrazu tutaj

Metoda 2: Programowo:

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

Wynik:

Działa w trybie poziomym i pionowym

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Projekt demonstracyjny - https://github.com/janeshsutharios/UIStackView-with-constraints

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

Jacek
źródło
4

Myślę, że można to wyjaśnić bardziej szczegółowo, aby można je było łatwiej zastosować do dowolnej liczby widoków wymagających stałych procentowych układów w superviewie.

Widok z lewej strony

  • Zakotwiczony do SuperView.Leading
  • Definiuje stałą wartość procentową jako mnożnik na SuperView.Height

Widoki pośrednie

  • Definiuje stałą wartość procentową jako mnożnik na SuperView.Height
  • Przypina leftgo po prawej stronie sąsiada

Widok z prawej strony

  • Nie definiuje stałego procentu (jest to reszta dostępnego widoku)
  • Przypina leftgo po prawej stronie sąsiada
  • Piny rightdoSuperView.Trailing

Wszystkie widoki

  • Określ ich niestacjonarne wysokości, zakotwiczając je do Top Layout Guide.Topi Top Layout Guide.bottom. W powyższej odpowiedzi należy zauważyć, że można to również zrobić, ustawiając równą wysokość sąsiedniego widoku.
JuJoDi
źródło