Raam vs piirid iOS-is

See artikkel on vastus, mille kirjutasin teemal Virna ülevool.

Lühike kirjeldus

  • raam = vaate asukoht ja suurus vanema vaate koordinaatsüsteemi abil (oluline vaate vanemasse paigutamiseks)
  • piire = vaate asukoht ja suurus oma koordinaatsüsteemi abil (oluline vaate sisu või alamvaate sisestamiseks enda sisse)

Üksikasjad

Raami meeldejätmiseks mõtlen seinale pildiraami. Pildiraam on nagu vaate piir. Saan pildi seinale riputada kuhu iganes tahan. Samamoodi võin vanema vaatesse paigutada vaate kuhu iganes soovin (nimetatakse ka supervaateks). Vanemavaade on nagu sein. Koordinaatsüsteemi lähtepunkt iOS-is on vasakul ülaservas. Saame vaadata oma vaate supervaate lähtepunkti, seades vaateraami x-y koordinaadid väärtusele (0, 0), mis on nagu meie pildi riputamine seina vasakus ülanurgas. Paremale liigutamiseks suurendage x, allapoole liikumiseks suurendage y.

Piirete meeldejätmiseks mõtlen korvpalliplatsile, kus mõnikord lööb korvpall piiridest välja. Te ajate palli kogu korvpalliväljakul, kuid tegelikult ei huvita teid, kus kohus ise asub. See võib asuda spordisaalis või väljaspool keskkooli või oma maja ees. See pole oluline. Tahad lihtsalt korvpalli mängida. Samamoodi hoolitseb vaate piiride koordinaatsüsteem ainult vaate enda eest. See ei tea midagi vanemvaates paikneva vaate kohta. Piiride alguspunkt (vaikimisi punkt (0, 0)) on vaate vasak vasak ülanurk. Selle vaatega seoses on esitatud kõik vaated. See on nagu korvpalli viimine platsi vasakpoolsesse vasakusse nurka.

Nüüd tuleb segadus, kui proovite võrrelda raame ja piire. Tegelikult pole see siiski nii hull, kui alguses tundub. Kasutagem mõnd pilti, et meid paremini mõista.

Raam vs piirid

Esimesel vasakpoolsel pildil on vaade, mis asub tema vanema vaate vasakus ülanurgas. Kollane ristkülik tähistab vaate raami. Paremal näeme vaadet uuesti, kuid seekord vanemvaadet ei näidata. Selle põhjuseks on asjaolu, et piirid ei tea vanema vaadet. Roheline ristkülik tähistab vaate piire. Punane punkt mõlemal pildil tähistab raami või piiride päritolu.

Raam
    päritolu = (0, 0)
    laius = 80
    kõrgus = 130
 
 Piirid
    päritolu = (0, 0)
    laius = 80
    kõrgus = 130

Nii et raam ja piirid olid sellel pildil täpselt samad. Vaatame näidet, kus nad erinevad.

 Raam
     päritolu = (40, 60) // see tähendab, x = 40 ja y = 60
     laius = 80
     kõrgus = 130
 
 Piirid
     päritolu = (0, 0)
     laius = 80
     kõrgus = 130

Nii näete, et raami x-y koordinaatide muutmine teisaldab selle vanemvaates. Kuid vaate sisu ise näeb ikkagi täpselt sama välja. Piiridel pole aimugi, et midagi on teisiti.

Siiani on nii raami kui ka piiride laius ja kõrgus olnud täpselt samad. See pole aga alati tõsi. Vaadake, mis juhtub, kui pöörame vaadet 20 kraadi päripäeva. (Pööramine toimub teisenduste abil. Lisateavet leiate dokumentatsioonist ning nendest vaadetest ja kihtidest.)

Raam
   päritolu = (20, 52) // Need on vaid umbkaudsed hinnangud.
   laius = 118
   kõrgus = 187
 
Piirid
   päritolu = (0, 0)
   laius = 80
   kõrgus = 130

Näete, et piirid on endiselt samad. Nad ei tea endiselt, et midagi on juhtunud! Raami väärtused on kõik muutunud.

Nüüd on natuke lihtsam näha kaadrite ja piiride erinevust, kas pole? Artikkel, millest te tõenäoliselt ei saa aru, raamid ja piirid, määratleb vaateraami kui

… Selle vaate väikseim piirdekast selle vanemate suhtes
koordinaatsüsteem, sealhulgas selle vaate suhtes rakendatud kõik teisendused.

Oluline on märkida, et kui vaade teisendatakse, muutub raam määratlematuks. Nii et seda kollast raami, mille ma joonistasin ülaltoodud pildil pööratud roheliste piiride ümber, ei ole tegelikult kunagi olemas. See tähendab, et kui pöörate, skaleerite või teete mõnda muud teisendust, siis ei tohiks te enam raami väärtusi kasutada. Piiride väärtusi saate siiski kasutada. Apple'i dokumendid hoiatavad:

Tähtis: kui vaate teisenduse atribuut ei sisalda identiteedi teisendust, on selle vaate raam määratlemata, nagu ka selle autoresizing käitumise tulemused.

Pigem kahetsusväärne automaatse muutmise pärast. Midagi saate siiski teha.

Apple'i dokumentide olek:

Teie vaate teisendusomaduste muutmisel teostatakse kõik teisendused vaate keskpunkti suhtes.

Nii et kui peate pärast teisenduse tegemist vanemas vaadet ümber liigutama, saate seda teha, muutes view.center koordinaate. Sarnaselt raamile kasutab kese ka vanema vaate koordinaatsüsteemi.

Olgem lahti meie rotatsioonist ja keskenduge piiridele. Siiani on piiride päritolu alati püsinud (0, 0). See ei pea aga nii olema. Mis saab siis, kui meie vaated omavad suurt alamvaadet, mis on liiga suur, et neid korraga kuvada? Teeme sellest suure pildi UIImageView. Siin on jälle meie teine ​​pilt ülalt, kuid seekord näeme, milline näeks välja meie vaate alamvaade.

Raam
    päritolu = (40, 60)
    laius = 80
    kõrgus = 130
 
Piirid
    päritolu = (0, 0)
    laius = 80
    kõrgus = 130

Ainult pildi vasak ülanurk mahub vaate piiridesse. Nüüd vaatame, mis juhtub, kui muudame piiride päritolu koordinaate.

Raam
    päritolu = (40, 60)
    laius = 80
    kõrgus = 130
 
Piirid
    päritolu = (280, 70)
    laius = 80
    kõrgus = 130

Raami ei ole supervaates liigutatud, kuid kaadrisisene sisu on muutunud, kuna piiride ristküliku päritolu algab vaate teisest osast. See on kogu UIScrollView idee ja selle alaklassid (näiteks UITableView). Lisateavet leiate jaotisest UIScrollView mõistmine.

Millal raami kasutada ja millal piire kasutada

Kuna raam seob vaate asukoha vanemvaates, kasutate seda väljastpoolt tehtavate muudatuste tegemisel, näiteks muutke selle laiust või leiad kauguse vaate ja selle vanema vaate ülaosa vahel.

Kasutage piire, kui teete sisemisi muudatusi, näiteks joonistate asju või korraldate vaated alamvaatesse. Kasutage ka piire, et saada pildi suurus, kui olete sellel mõnda ümberpaigutust teinud.

Artiklid edasiseks uurimiseks:

Apple'i dokumendid

  • Vaategeomeetria
  • Vaated
  • Vaate- ja aknaarhitektuur

Muud ressursid

  • Tõenäoliselt ei saa te raamidest ja piiridest aru
  • iOS-i põhialused: raamid, piirid ja CGGeometry
  • CS193p 5. loeng - vaated, joonistamine, animatsioon

Harjuta ennast

Lisaks ülaltoodud artiklite lugemisele aitab see mind palju ka testirakenduse loomisel. Võite proovida teha midagi sarnast. (Idee sain sellest videokursusest, kuid kahjuks pole see tasuta.)

Siin on teie viite kood:

import UIKit
 
   klassi ViewController: UIViewController {
 
 
    @IBOutlet nõrk var myView: UIView!
 
    // Sildid
    @IBOutlet nõrk var frameX: UILabel!
    @IBOutlet nõrk var frameY: UILabel!
    @IBOutlet nõrk var frameWidth: UILabel!
    @IBOutlet nõrk var frameHeight: UILabel!
    @IBOutlet nõrk var piiridX: UILabel!
    @IBOutlet nõrgad erinevad piiridY: UILabel!
    @IBOutlet nõrk var piiridLaius: UILabel!
    @IBOletlet nõrk var piiridKõrgus: UILabel!
    @IBOutlet nõrk var centerX: UILabel!
    @IBOutlet nõrk var keskusesY: UILabel!
    @IBOletlet nõrk var pöörlemine: UILabel!
 
    // Liugurid
    @IBOutlet nõrk var frameXSlider: UISlider!
    @IBOutlet nõrk var frameYSlider: UISlider!
    @IBOutlet nõrk var frameWidthSlider: UISlider!
    @IBOutlet nõrk var frameHeightSlider: UISlider!
    @IBOutlet nõrk var piiridXSlider: UISlider!
    @IBOutlet nõrk var piiridYSlider: UISlider!
    @IBOletlet nõrk var piiridWidthSlider: UISlider!
    @IBOletlet nõrgad erinevad piiridHeightSlider: UISlider!
    @IBOutlet nõrk var centerXSlider: UISlider!
    @IBOutlet nõrk var centerYSlider: UISlider!
    @IBOutlet nõrk var rotationSlider: UISlider!
 
    // Liuguri toimingud
    @IBAction func frameXSliderChanged (saatja: AnyObject) {
        myView.frame.origin.x = CGFloat (frameXSlider.value)
        updateLabels ()
    }
    @IBAction func frameYSliderChanged (saatja: AnyObject) {
        myView.frame.origin.y = CGFloat (frameYSlider.value)
        updateLabels ()
    }
    @IBAction func frameWidthSliderChanged (saatja: AnyObject) {
        myView.frame.size.width = CGFloat (frameWidthSlider.value)
        updateLabels ()
    }
    @IBAction funktsioon frameHeightSliderChanged (saatja: AnyObject) {
        myView.frame.size.height = CGFloat (frameHeightSlider.value)
        updateLabels ()
    }
    @IBAction funktsiooni piiridXSliderChanged (saatja: AnyObject) {
        myView.bounds.origin.x = CGFloat (boundsXSlider.value)
       updateLabels ()
    }
    @IBAction func boundsYSliderChanged (saatja: AnyObject) {
        myView.bounds.origin.y = CGFloat (boundsYSlider.value)
        updateLabels ()
    }
    @IBAction funktsiooni piiridWidthSliderChanged (saatja: AnyObject) {
        myView.bounds.size.width = CGFloat (boundsWidthSlider.value)
        updateLabels ()
    }
    @IBAction funktsiooni piiridHeightSliderChanged (saatja: AnyObject) {
        myView.bounds.size.height = CGFloat (boundsHeightSlider.value)
        updateLabels ()
    }
    @IBAction funktsioonikeskusXSliderChanged (saatja: AnyObject) {
        myView.center.x = CGFloat (centerXSlider.value)
        updateLabels ()
    }
    @IBAction funktsioonikeskusYSliderChanged (saatja: AnyObject) {
        myView.center.y = CGFloat (centerYSlider.value)
        updateLabels ()
    }
    @IBAction func rotationSliderChanged (saatja: AnyObject) {
        lase pöörlemist = CGAffineTransform (rotatsiooninurk: CGFloat (rotatsioonSlider.value))
        myView.transform = pöörlemine
        updateLabels ()
    }
 
    privaatne func updateLabels () {
 
        frameX.text = “frame x = \ (Int (myView.frame.origin.x))”
        frameY.text = “frame y = \ (Int (myView.frame.origin.y))”
        frameWidth.text = “kaadri laius = \ (keskmine (myView.raami.laius))”
        frameHeight.text = “kaadri kõrgus = \ (keskmine (myView.frame.height))”
        boundsX.text = “bounds x = \ (Int (myView.bounds.origin.x))”
        boundsY.text = “piirab y = \ (keskmine (myView.bounds.origin.y))”
        boundsWidth.text = “bounds width = \ (Int (myView.bounds.width))”
        boundsHeight.text = “piiride kõrgus = \ (keskmine (myView.bounds.height))”
        centerX.text = “kese x = \ (keskmine (myView.center.x))”
        centerY.text = “kese y = \ (keskmine (myView.center.y))”
        rotation.text = “rotatsioon = \ ((rotatsioonSlider.value))”
 
    }
 
}