XCode: Landshaft va portret rejimlari orasidagi tartibni qanday o'zgartirish mumkin

Portret rejimda men bir-birining tepasida tepadan qarama-qarshi ko'rinishga ega bo'lgan to'rtta ko'rinishga egaman (rasmga qarang).

portrait view

I then want to change the position of the views relative to one another when the device transitions to landscape (see image two).landscape view

Men 4-rasmga 2-va 3-sonli ko'rinishlar bilan birga harakat qilishni xohlayman.

Ba'zi tuzilish shartlari:

  • view 1 is attached to the top of the view controller in both landscape and portrait.
  • view 4 is attached to the left, right and bottom margins of the view controller in portrait mode.
  • Views 2, 3 & 4 are centered horizontally within the portrait view.

Turli tartibga erishishning eng yaxshi usuli nima?

Would the most elegant solution be to make a reference to the constraints in the view controllers code and activate and deactivate them in viewWillTransition? Or is there a way to use vary for traits to achieve this (I can imagine views 2, 3 & 4 being centered horizontally would make this hard to achieve, as well as adding the new constraints for view 4 in landscape mode)?

5
Menimcha, viewWillTransition afzal usul bo'lib, lekin buni amalga oshirishning yaxshiroq yo'llaridan biri xabardor ekanligiga ishonchim komil emas
qo'shib qo'ydi muallif Fred White, manba
Menimcha, viewWillTransition afzal usul bo'lib, lekin buni amalga oshirishning yaxshiroq yo'llaridan biri xabardor ekanligiga ishonchim komil emas
qo'shib qo'ydi muallif Fred White, manba
Menimcha, viewWillTransition afzal usul bo'lib, lekin buni amalga oshirishning yaxshiroq yo'llaridan biri xabardor ekanligiga ishonchim komil emas
qo'shib qo'ydi muallif Fred White, manba
"xususiyatlar uchun farq" - XCode 8 ning o'lchov klassi. Ammo ma'lum bir o'lchov sinfiga bitta cheklov qo'shsangiz, u barchaga qo'shiladi. Siz faqat 4 ko'rinishda yangi cheklovlar to'plamiga muhtoj bo'lgan mavjud bo'lgan cheklovlarni o'zgartirishingiz mumkin.
qo'shib qo'ydi muallif Fred White, manba
"xususiyatlar uchun farq" - XCode 8 ning o'lchov klassi. Ammo ma'lum bir o'lchov sinfiga bitta cheklov qo'shsangiz, u barchaga qo'shiladi. Siz faqat 4 ko'rinishda yangi cheklovlar to'plamiga muhtoj bo'lgan mavjud bo'lgan cheklovlarni o'zgartirishingiz mumkin.
qo'shib qo'ydi muallif Fred White, manba

6 javoblar

Biz turli cheklovlarni o'rnatdik va ularni yo'nalish o'zgarishi asosida ularni yoqish/o'chirish uchun foydalanar edik. Ammo bugungi kunda o'lchov sinflarini ishlatish va "xususiyatlarga qarab farq qilishi" mumkin.

Misol uchun, oddiy ko'rinish bilan boshlayman va kichik kenglik kattaligi sinfini tanlayman va keyin "Xususiyatlar uchun o'zgaruvchan" ni tanlang:

enter image description here

Keyin tegishli cheklovlarni qo'shib, "O'zgarishlarni tugatgan" tugmasini bosing:

enter image description here

So'ngra "muntazam kenglik kattaligi" ni tanlab, jarayonni takrorlang ("xususiyatlar uchun farq", cheklovlarni qo'shing, "Tayyorlangan tugma" ustiga bosing:

enter image description here

Keyinchalik kichik hajmli sinflar va muntazam kenglik kattaligi uchun faol bo'lgan cheklovlarning mutlaqo boshqa to'plamiga ega bo'lgan sahna bilan yakunlanasiz. Ie. ilovani ishga tushirganimda, agar qurilma qaytarsa, yangi cheklovlar faollashadi:

enter image description here

Qo'shimcha ma'lumot olish uchun WWDC 2016 videolarini uyg'un tartibda ko'rishingiz mumkin:

15
qo'shib qo'ydi
Ha, siz yangi o'lchov sinfini tanlaganingizda, ularni xohlagan joylaringizni ko'chiring, cheklovlarni qo'shing va ishingiz tugadi. Sizning savolingizga nuqta qo'yganim yo'q, deb o'ylayman: Men siz tushunmaydigan o'lchamli sinflar bilan bog'liq muammolarga duch kelishingiz kerak. Ehtimol siz o'lchamli sinf bilan bog'liq bo'lgan muammolarni tushuntira olasiz ...
qo'shib qo'ydi muallif Rob, manba
Qurilma yo'nalishini aniqlash uchun o'lchov sinflarini ishlatmang. Hajmi sinf ("ixcham" va "muntazam") va qurilma yo'nalishi ("portret" va "landshaft") aloqador emas. Hozirda barcha iPad o'lchamlari sinflari "muntazam" bo'lib, qurilmani qaytadan aylantirganda o'zgarmaydi. IPhone bilan; portret rejimida ayrim modellar "ixcham" kenglik, ba'zilari esa "muntazam" kenglik hisoblanadi va agar siz o'lchov sinfidagi o'zgarishlarni aniqlashga tayanilsangiz, unda aylanish paytida har xil bo'ladi.
qo'shib qo'ydi muallif Vince O'Sullivan, manba
Batafsil javob uchun tashakkur, shuning uchun boshqa o'lchov sinflariga ta'sir qilmasdan (masalan, landshaftga o'tish, qizil va ko'k ko'rinishni yonma-yon olib, so'ng cheklovlarni qo'shib) xususiyatlarni o'zgartirish uchun ko'rinishni o'zgartirish mumkinmi?
qo'shib qo'ydi muallif Fred White, manba

Biz turli cheklovlarni o'rnatdik va ularni yo'nalish o'zgarishi asosida ularni yoqish/o'chirish uchun foydalanar edik. Ammo bugungi kunda o'lchov sinflarini ishlatish va "xususiyatlarga qarab farq qilishi" mumkin.

Misol uchun, oddiy ko'rinish bilan boshlayman va kichik kenglik kattaligi sinfini tanlayman va keyin "Xususiyatlar uchun o'zgaruvchan" ni tanlang:

enter image description here

Keyin tegishli cheklovlarni qo'shib, "O'zgarishlarni tugatgan" tugmasini bosing:

enter image description here

So'ngra "muntazam kenglik kattaligi" ni tanlab, jarayonni takrorlang ("xususiyatlar uchun farq", cheklovlarni qo'shing, "Tayyorlangan tugma" ustiga bosing:

enter image description here

Keyinchalik kichik hajmli sinflar va muntazam kenglik kattaligi uchun faol bo'lgan cheklovlarning mutlaqo boshqa to'plamiga ega bo'lgan sahna bilan yakunlanasiz. Ie. ilovani ishga tushirganimda, agar qurilma qaytarsa, yangi cheklovlar faollashadi:

enter image description here

Qo'shimcha ma'lumot olish uchun WWDC 2016 videolarini uyg'un tartibda ko'rishingiz mumkin:

15
qo'shib qo'ydi
Ha, siz yangi o'lchov sinfini tanlaganingizda, ularni xohlagan joylaringizni ko'chiring, cheklovlarni qo'shing va ishingiz tugadi. Sizning savolingizga nuqta qo'yganim yo'q, deb o'ylayman: Men siz tushunmaydigan o'lchamli sinflar bilan bog'liq muammolarga duch kelishingiz kerak. Ehtimol siz o'lchamli sinf bilan bog'liq bo'lgan muammolarni tushuntira olasiz ...
qo'shib qo'ydi muallif Rob, manba
Qurilma yo'nalishini aniqlash uchun o'lchov sinflarini ishlatmang. Hajmi sinf ("ixcham" va "muntazam") va qurilma yo'nalishi ("portret" va "landshaft") aloqador emas. Hozirda barcha iPad o'lchamlari sinflari "muntazam" bo'lib, qurilmani qaytadan aylantirganda o'zgarmaydi. IPhone bilan; portret rejimida ayrim modellar "ixcham" kenglik, ba'zilari esa "muntazam" kenglik hisoblanadi va agar siz o'lchov sinfidagi o'zgarishlarni aniqlashga tayanilsangiz, unda aylanish paytida har xil bo'ladi.
qo'shib qo'ydi muallif Vince O'Sullivan, manba
Batafsil javob uchun tashakkur, shuning uchun boshqa o'lchov sinflariga ta'sir qilmasdan (masalan, landshaftga o'tish, qizil va ko'k ko'rinishni yonma-yon olib, so'ng cheklovlarni qo'shib) xususiyatlarni o'zgartirish uchun ko'rinishni o'zgartirish mumkinmi?
qo'shib qo'ydi muallif Fred White, manba

Biz turli cheklovlarni o'rnatdik va ularni yo'nalish o'zgarishi asosida ularni yoqish/o'chirish uchun foydalanar edik. Ammo bugungi kunda o'lchov sinflarini ishlatish va "xususiyatlarga qarab farq qilishi" mumkin.

Misol uchun, oddiy ko'rinish bilan boshlayman va kichik kenglik kattaligi sinfini tanlayman va keyin "Xususiyatlar uchun o'zgaruvchan" ni tanlang:

enter image description here

Keyin tegishli cheklovlarni qo'shib, "O'zgarishlarni tugatgan" tugmasini bosing:

enter image description here

So'ngra "muntazam kenglik kattaligi" ni tanlab, jarayonni takrorlang ("xususiyatlar uchun farq", cheklovlarni qo'shing, "Tayyorlangan tugma" ustiga bosing:

enter image description here

Keyinchalik kichik hajmli sinflar va muntazam kenglik kattaligi uchun faol bo'lgan cheklovlarning mutlaqo boshqa to'plamiga ega bo'lgan sahna bilan yakunlanasiz. Ie. ilovani ishga tushirganimda, agar qurilma qaytarsa, yangi cheklovlar faollashadi:

enter image description here

Qo'shimcha ma'lumot olish uchun WWDC 2016 videolarini uyg'un tartibda ko'rishingiz mumkin:

15
qo'shib qo'ydi
Ha, siz yangi o'lchov sinfini tanlaganingizda, ularni xohlagan joylaringizni ko'chiring, cheklovlarni qo'shing va ishingiz tugadi. Sizning savolingizga nuqta qo'yganim yo'q, deb o'ylayman: Men siz tushunmaydigan o'lchamli sinflar bilan bog'liq muammolarga duch kelishingiz kerak. Ehtimol siz o'lchamli sinf bilan bog'liq bo'lgan muammolarni tushuntira olasiz ...
qo'shib qo'ydi muallif Rob, manba
Qurilma yo'nalishini aniqlash uchun o'lchov sinflarini ishlatmang. Hajmi sinf ("ixcham" va "muntazam") va qurilma yo'nalishi ("portret" va "landshaft") aloqador emas. Hozirda barcha iPad o'lchamlari sinflari "muntazam" bo'lib, qurilmani qaytadan aylantirganda o'zgarmaydi. IPhone bilan; portret rejimida ayrim modellar "ixcham" kenglik, ba'zilari esa "muntazam" kenglik hisoblanadi va agar siz o'lchov sinfidagi o'zgarishlarni aniqlashga tayanilsangiz, unda aylanish paytida har xil bo'ladi.
qo'shib qo'ydi muallif Vince O'Sullivan, manba
Batafsil javob uchun tashakkur, shuning uchun boshqa o'lchov sinflariga ta'sir qilmasdan (masalan, landshaftga o'tish, qizil va ko'k ko'rinishni yonma-yon olib, so'ng cheklovlarni qo'shib) xususiyatlarni o'zgartirish uchun ko'rinishni o'zgartirish mumkinmi?
qo'shib qo'ydi muallif Fred White, manba

Men cheklovlar majmuasidan foydalanaman va yo'nalishga ko'ra yoqaman/o'chirib qo'yaman.

var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
var initialOrientation = true
var isInPortrait = false

override func viewDidLoad() {
    super.viewDidLoad()
   //add any subviews here
    view.turnOffAutoResizing()        
   //add constraints here....
   //   common constraints you can set their isActive = true
   //   otherwise, add in to portrait(p) and landscape(l) arrays
}

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        view.setOrientation(p, l)
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            view.setOrientation(p, l)
        }
    }
}
extension UIView {
    public func turnOffAutoResizing() {
        self.translatesAutoresizingMaskIntoConstraints = false
        for view in self.subviews as [UIView] {
           view.translatesAutoresizingMaskIntoConstraints = false
        }
    }
    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
    public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
        NSLayoutConstraint.deactivate(l)
        NSLayoutConstraint.deactivate(p)
        if self.bounds.width > self.bounds.height {
            NSLayoutConstraint.activate(l)
        } else {
            NSLayoutConstraint.activate(p)
        }
    }
}

Mening ilovam ulkan va iPad (split yoki slaydni ko'rinishni ishlatmasangiz) har doim oddiy o'lchamli bo'lgani uchun, portretni yoki peyzamni o'lchamli sinflardan boshqa narsani ishlatib ni talab qilish kerak. Bundan tashqari, "viewWillLoadSubviews ()" o'rniga "viewWillTransistion (toSize:) yoki viewDidLoadSubviews() dan foydalanishingiz mumkin, biroq bularni bir martadan ortiq bajarilishi mumkin orientatsiya o'zgarishi!

1
qo'shib qo'ydi
Siz buni mumkin hikoyalar orqali amalga oshirishingiz mumkin, lekin IB faqatgina "dizayn vaqti" vositasidir. Buning ma'nosi (men bunga duch keldim) shundaki, agar orientatsiya o'zgarishini sinab ko'rish imkonsiz bo'lsa, ayniqsa, iPad uchun zerikarli bo'ladi.
qo'shib qo'ydi muallif dfd, manba
Javobingiz uchun tashakkur, ideal tarzda hikoyangiz orqali buni qilishni xohlardim, lekin bu yaxshi hikoya podshohi orqali amalga oshirilmasa yaxshi bo'ladi!
qo'shib qo'ydi muallif Fred White, manba

Men cheklovlar majmuasidan foydalanaman va yo'nalishga ko'ra yoqaman/o'chirib qo'yaman.

var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
var initialOrientation = true
var isInPortrait = false

override func viewDidLoad() {
    super.viewDidLoad()
   //add any subviews here
    view.turnOffAutoResizing()        
   //add constraints here....
   //   common constraints you can set their isActive = true
   //   otherwise, add in to portrait(p) and landscape(l) arrays
}

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        view.setOrientation(p, l)
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            view.setOrientation(p, l)
        }
    }
}
extension UIView {
    public func turnOffAutoResizing() {
        self.translatesAutoresizingMaskIntoConstraints = false
        for view in self.subviews as [UIView] {
           view.translatesAutoresizingMaskIntoConstraints = false
        }
    }
    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
    public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
        NSLayoutConstraint.deactivate(l)
        NSLayoutConstraint.deactivate(p)
        if self.bounds.width > self.bounds.height {
            NSLayoutConstraint.activate(l)
        } else {
            NSLayoutConstraint.activate(p)
        }
    }
}

Mening ilovam ulkan va iPad (split yoki slaydni ko'rinishni ishlatmasangiz) har doim oddiy o'lchamli bo'lgani uchun, portretni yoki peyzamni o'lchamli sinflardan boshqa narsani ishlatib ni talab qilish kerak. Bundan tashqari, "viewWillLoadSubviews ()" o'rniga "viewWillTransistion (toSize:) yoki viewDidLoadSubviews() dan foydalanishingiz mumkin, biroq bularni bir martadan ortiq bajarilishi mumkin orientatsiya o'zgarishi!

1
qo'shib qo'ydi
Siz buni mumkin hikoyalar orqali amalga oshirishingiz mumkin, lekin IB faqatgina "dizayn vaqti" vositasidir. Buning ma'nosi (men bunga duch keldim) shundaki, agar orientatsiya o'zgarishini sinab ko'rish imkonsiz bo'lsa, ayniqsa, iPad uchun zerikarli bo'ladi.
qo'shib qo'ydi muallif dfd, manba
Javobingiz uchun tashakkur, ideal tarzda hikoyangiz orqali buni qilishni xohlardim, lekin bu yaxshi hikoya podshohi orqali amalga oshirilmasa yaxshi bo'ladi!
qo'shib qo'ydi muallif Fred White, manba

Men cheklovlar majmuasidan foydalanaman va yo'nalishga ko'ra yoqaman/o'chirib qo'yaman.

var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
var initialOrientation = true
var isInPortrait = false

override func viewDidLoad() {
    super.viewDidLoad()
   //add any subviews here
    view.turnOffAutoResizing()        
   //add constraints here....
   //   common constraints you can set their isActive = true
   //   otherwise, add in to portrait(p) and landscape(l) arrays
}

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        view.setOrientation(p, l)
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            view.setOrientation(p, l)
        }
    }
}
extension UIView {
    public func turnOffAutoResizing() {
        self.translatesAutoresizingMaskIntoConstraints = false
        for view in self.subviews as [UIView] {
           view.translatesAutoresizingMaskIntoConstraints = false
        }
    }
    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
    public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
        NSLayoutConstraint.deactivate(l)
        NSLayoutConstraint.deactivate(p)
        if self.bounds.width > self.bounds.height {
            NSLayoutConstraint.activate(l)
        } else {
            NSLayoutConstraint.activate(p)
        }
    }
}

Mening ilovam ulkan va iPad (split yoki slaydni ko'rinishni ishlatmasangiz) har doim oddiy o'lchamli bo'lgani uchun, portretni yoki peyzamni o'lchamli sinflardan boshqa narsani ishlatib ni talab qilish kerak. Bundan tashqari, "viewWillLoadSubviews ()" o'rniga "viewWillTransistion (toSize:) yoki viewDidLoadSubviews() dan foydalanishingiz mumkin, biroq bularni bir martadan ortiq bajarilishi mumkin orientatsiya o'zgarishi!

1
qo'shib qo'ydi
Siz buni mumkin hikoyalar orqali amalga oshirishingiz mumkin, lekin IB faqatgina "dizayn vaqti" vositasidir. Buning ma'nosi (men bunga duch keldim) shundaki, agar orientatsiya o'zgarishini sinab ko'rish imkonsiz bo'lsa, ayniqsa, iPad uchun zerikarli bo'ladi.
qo'shib qo'ydi muallif dfd, manba
Javobingiz uchun tashakkur, ideal tarzda hikoyangiz orqali buni qilishni xohlardim, lekin bu yaxshi hikoya podshohi orqali amalga oshirilmasa yaxshi bo'ladi!
qo'shib qo'ydi muallif Fred White, manba