Кадр подпредставлений не обновляется после команды view.center - PullRequest
2 голосов
/ 25 октября 2019

То, что у меня есть, это различные виды, как показано на рисунке: основной вид - container, внутри которого - boxSentence, внутри boxSentence - subView, а внутри subViewразличные текстовые метки с серой рамкой boxWord. Затем есть еще одно представление boxAnswer, которое представляет собой перетаскиваемый элемент, который я создал и который можно отбросить только внутри boxWord (я передаю boxWord в свой пользовательский класс boxAnswer, чтобы проверить его положение (фрейм)).

Main scenario

В этом сценарии все работает нормально, boxAnswer можно поместить только внутри поля ввода

Working scenario

Затем для настройки графики всего вида я хочу поместить мой subView со всеми его фактическими подпредставлениями в центр boxSentence. Для этого я использовал subView.center = boxSentence.center и получил то, что хотел.

subView in the center

Теперь проблема возникает, когда я пытаюсь перетащить boxAnswer в новую позицию boxWord, это не работает, но если я попытаюсь перетащить его туда, где было boxWord, прежде чем переместить его в центр, это сработает.

Problem here

Кажется, что когда вы делаете subView.center = boxSentence.center, это влияет только на кадр subView, но это не влияет на кадрыего подпредставления. Любые предложения о том, как решить проблему?

КОД:

// creo box dove inserire la frase
let boxSentence = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: container.frame.height/2))
container.addSubview(boxSentence)
boxSentence.backgroundColor = hexStringToUIColor(hex: "#49eb34")

let subView = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: 70))


let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label1.text = esercizio.ctsex![0].first_sentence
label1.backgroundColor = UIColor.yellow
label1.sizeToFit()

let boxWord = UIView(frame: CGRect(x: label1.frame.maxX, y: 0, width: 100, height: 60))
boxWord.backgroundColor = UIColor.gray

let label2 = UILabel(frame: CGRect(x: boxWord.frame.maxX, y: 0, width: 100, height: 100))
label2.text = esercizio.ctsex![0].second_sentence
label2.backgroundColor = UIColor.yellow
label2.sizeToFit()

subView.addSubview(label1)
subView.addSubview(boxWord)
subView.addSubview(label2)
subView.backgroundColor = UIColor.purple
boxSentence.addSubview(sottoView)
subView.frame = CGRect(x: 0, y: 0, width: label2.frame.maxX-label1.frame.minX, height: 80)
subView.center = boxSentence.center


let coordrisposta = CGRect(x: boxFrase.frame.minX, y: boxFrase.frame.maxY, width: 80.0, height: 40.0)
let boxAnswer = DragObject(frame: coordrisposta, vistap: boxWord)
boxAnswer.backgroundColor = UIColor.red

container.addSubview(rispostaBox)

КЛАСС DragObject OF boxAnser:

import UIKit

// CLASSE CHE CREA UNA VISTA CHE PUO ESSERE SPOSTATA SOLO ALL'INTERNO DI UNA VISTA PASSATA DA PARAMETRO

class DragObject: UIView {

    var vista: UIView
    var initcoord: CGRect

    init(frame: CGRect, vistap: UIView){
        self.vista = vistap
        self.initcoord = frame
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch began")
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
       var touch : UITouch! = touches.first as UITouch?
       self.center = touch.location(in: self.superview)        
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        var coorv = vista.frame
        print(coorv)

        let coord1 = (touches.first?.location(in: self.superview))!
        let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
        let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)

        if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
            print("OK")
            self.frame = vista.frame
        } else {
            print("fuori")
            self.frame = initcoord
        }
    }
}

1 Ответ

1 голос
/ 26 октября 2019

Кадры UIView - это его координаты относительно родительских границ (внутренняя система координат UIView, которая является системой координат для подпредставления этого представления). Например, у нас есть UIViewController с двумя представлениями:

let redView = UIView()
redView.backgroundColor = .red
redView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
self.view.addSubview(redView)

let greenView = UIView()
greenView.backgroundColor = .green
greenView.frame = CGRect(x: 25, y:25, width:50, height: 50)
redView.addSubview(greenView)

print(redView.frame)
/*
(20.0, 20.0, 100.0, 100.0)
redView is placed self.view.bounds.origin.x + 20 and self.view.bounds.origin.y + 20
*/
print(greenView.frame)
/*
(25.0, 25.0, 50.0, 50.0)
green is placed redView.bounds.origin.x + 25 and redView.bounds.origin.y + 25
*/
print(redView.convert(greenView.frame, to: self.view))
/*
(45.0, 45.0, 50.0, 50.0)
converted frame of greenView from redViews bounds to of self.view bounds.
*/

Таким образом, проблема внутри DragObject, вы передаете фрейм и координаты представления, которые отражают их место относительно источника представления subView. Между тем DragObject является подпредставлением вида контейнера, и когда вы получаете сенсорные координаты, вы получаете координаты относительно вида контейнера.
Вы можете исправить это, преобразовав vista.frame в систему координат суперпредставления DragObject. Вот полный код функции переопределения функции touchesEnded (_ touch: Установить, с событием: UIEvent?) В DragObject

var coorv = vista.superview!.convert(vista.frame, to: self.superview!)
print(coorv)

let coord1 = (touches.first?.location(in: self.superview))!
let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)

if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
    print("OK")
    self.frame = coorv
} else {
    print("fuori")
    self.frame = initcoord
}
...