Квадратичная кривая не отображается правильно на разных устройствах - PullRequest
1 голос
/ 09 июля 2019

Я пытаюсь нарисовать путь Безье с квадратичной кривой посередине.Кривая работает хорошо на iPhone 8 и XS, но не реагирует (то есть не отображается правильно) на других устройствах.

Ниже приведено изображение кривой в iPhone XS (правильно)

enter image description here

и iPhone XR (неверно)

enter image description here

Я пытался использовать ограничение представлениячтобы получить среднее значение линии, но каким-то образом она все еще не работает

Вот код, где я рисую путь:

//self.viewTabBorder is the grey line, which is a uiview with 1 pixel height
override func viewWillAppear(_ animated: Bool) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: self.viewTabBorder.center.x - self.btnHome.frame.width + 20, y: 0))
        path.addQuadCurve(to: CGPoint(x: self.viewTabBorder.center.x + self.btnHome.frame.size.width - 20, y: 0), controlPoint: CGPoint(x: self.viewTabBorder.center.x, y: self.btnHome.frame.height + 5))
        path.addLine(to: CGPoint(x: self.viewTabBorder.center.x + self.btnHome.frame.size.width - 20, y: 0))

        let line = CAShapeLayer()
        line.path = path.cgPath
        line.strokeColor = UIColor(red: 224, green: 224, blue: 224).cgColor
        line.fillColor = UIColor.white.cgColor
        self.view.layer.addSublayer(line)
        self.viewTabBorder.layer.addSublayer(line)
    }

Может кто-нибудь показать мне, что мне не хватает?Заранее большое спасибо!

1 Ответ

1 голос
/ 09 июля 2019

Пара наблюдений:

  1. Вы определяете пути для подслоев к представлениям.Делать это в viewWillAppear слишком рано.Механизм компоновки может не выполняться с применением ограничений, помещая представления в их окончательное местоположение.Выполните определение путей в viewDidLayoutSubviews, а не в viewWillAppear (ни viewDidLoad, ни viewWillLayoutSubviews).

    Это также обладает достоинством, которое вы должны когда-либо изменитьВаше приложение для поддержки нескольких ориентаций или внесения любых изменений, которые влияют на ограничения в представлении, это viewDidLayoutSubviews, к которому мы будем обращаться снова, поэтому эти подслои будут должным образом обновляться по мере необходимости.Если вы используете viewWillAppear, ваше приложение не будет поддерживать динамические изменения ваших представлений (если вам это когда-нибудь понадобится).

  2. При этом помните, что viewDidLayoutSubviews можно вызватьмногократно.Таким образом, вы можете, например, добавить подслои в viewDidLoad, но обновить их пути в viewDidLayoutSubviews.

  3. Вероятно, здесь нет проблем, но я бы посоветовал вам избежатьиспользуя frame или center при определении пути для подслоя.Помните, что эти два свойства определены в системе координат их суперпредставления. Я бы посоветовал вам всегда использовать bounds представления (определенного в собственной системе координат представления), а не frame (определенногов системе координат его суперпредставления) при попытке определить путь для подслоя.И если вы хотите, например, горизонтальный центр вида при определении пути подслоя, используйте bounds.midX, а не center.x.

    Иногда это не имеет значения (если представление переходит от края ккрай в своем супервидении), но (а) оно предполагает неправильное понимание различных систем координат;и (b) если вы когда-либо добавите безопасные области или иным образом отрегулируете расположение вида, использование frame / center доставит вам неприятности.


Aнемного более продвинутая концепция: как только у вас возникнет непосредственная проблема, вы можете рассмотреть возможность перемещения этой конфигурации подпредставлений в подкласс UIView (с использованием его метода layoutSubviews), возможно, даже сделав его классом @IBDesignable, чтобы вы могли видетьэто отображается в Интерфейсном Разработчике.Или другой подход - обернуть это в контроллер представления контейнера.Но в любом случае, это может помочь предотвратить «вздутие» контроллера представления.Вероятно, это немного выходит за рамки этого вопроса, но что-то нужно учитывать при продвижении вперед.

...