Градиент не применяется для полного просмотра на большом экране

#ios #swift #xcode #uiview #uikit

Вопрос:

Я реализую код для применения диагонального градиента к различным видам. он отлично работал для всех небольших видов и всех видов на небольших экранах, но на симуляторе iPhone 13 Pro Max он не применяется к полному виду и оставляет некоторую часть справа. Я только заметил, что даже в некоторых других видах, которые шире, этот градиент применяется только примерно на 80% по ширине. Вот скриншот, как он отображается в одном представлении:

введите описание изображения здесь

Это не относится к правой части представления, и радиус правого угла невидим. Вот код для градиента:

 func applyGradientDiagonal(isVertical: Bool, colorArray: [UIColor]) {  layer.sublayers?.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() })   let gradientLayer = CAGradientLayer()  gradientLayer.colors = colorArray.map({ $0.cgColor })  if isVertical {  //top to bottom  gradientLayer.locations = [0.0, 1.0]  } else {  //left to right  gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)  gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)  }   backgroundColor = .clear  gradientLayer.frame = bounds  layer.insertSublayer(gradientLayer, at: 0)  }  

И я звоню по этому viewDidLoad() поводу вот так:

 self.viewTAGradient.applyGradientDiagonal(isVertical: false, colorArray: [UIColor.init(named: "gradient1")!, UIColor.init(named: "gradient2")!, UIColor.init(named: "gradient3")!])  

Я искал некоторые решения и даже пытался назвать это так, но это тоже не сработало:

 override func viewDidLayoutSubviews() {    self.viewTAGradient.applyGradientDiagonal(isVertical: false, colorArray: [UIColor.init(named: "gradient1")!, UIColor.init(named: "gradient2")!, UIColor.init(named: "gradient3")!])    }  

Изменить: Новое обновление: проблема заключается во всех градиентах на iPhone 13 pro max. Я скопировал некоторые коды из Интернета для градиентов и создал новый контроллер вида с одним видом фиксированной высоты, прикрепленным сверху, и все они сдвинуты влево на 13 pro max. однако отлично работает на других устройствах. вот скриншоты: введите описание изображения здесь введите описание изображения здесь

Кто-нибудь может мне помочь, почему на одном конкретном устройстве оно так себя ведет?

Комментарии:

1. Правильно ли вы установили ограничения viewTAGradient ?

2. Это должно работать, когда вы вызываете applyGradientDiagonal(isVertical:colorArray:) внутри viewDidLayoutSubviews(). Хотя это работает на моей машине. Не могли бы вы показать больше примеров кода, например, как настроить «viewTAGradient»?

3. @kyaw.monkey Я добавил более подробную информацию.

4. @Sweeper Я просто вызываю их внутри горизонтальной стопки фиксированной высоты = 180. При заполнении поровну на расстоянии 20 они должны создаваться автоматически. См. Выше после редактирования цвет BG применяется правильно, но градиент не будет

5. Проверьте свои ограничения компоновки…. предполагая , что вы viewTAGradient являетесь стандартом UIView , правильно ли он имеет размер, если вы зададите ему цвет фона вместо вызова applyGradientDiagonal() ?

Ответ №1:

Нет причин, по которым градиент будет вести себя по-другому на iPhone 13 Pro Max, поэтому я предполагаю (не видя вашего полного макета), что это будет связано с ограничениями или когда вы на самом деле звоните applyGradientDiagonal() .

Возможно, вам будет намного проще получить надежные результаты, создав подклассы UIView и поместив код градиента внутрь layoutSubview() .

Вот простой пример:

 class MyGradientView: UIView {    var colorArray: [UIColor] = [] {  didSet {  setNeedsLayout()  }  }  var vertical: Bool = true {  didSet {  setNeedsLayout()  }  }    static override var layerClass: AnyClass {  return CAGradientLayer.self  }    override func layoutSubviews() {  super.layoutSubviews()  guard let layer = layer as? CAGradientLayer else { return }  layer.colors = colorArray.map({ $0.cgColor })  if vertical {  // top-down gradient  layer.startPoint = CGPoint(x: 0.5, y: 0.0)  layer.endPoint = CGPoint(x: 0.5, y: 1.0)  } else {  // diagonal gradient  layer.startPoint = CGPoint(x: 0.0, y: 0.0)  layer.endPoint = CGPoint(x: 1.0, y: 1.0)  }  }  }  

и пример контроллера представления для демонстрации:

 class GradientTestViewController: UIViewController {    override func viewDidLoad() {  super.viewDidLoad()    let stack = UIStackView()  stack.axis = .vertical  stack.spacing = 8  stack.distribution = .fillEqually    let colorPairs: [[UIColor]] = [  [.blue, .cyan],  [.red, .yellow],  [.blue, .yellow, .red],  ]    // 3 pairs of gradient views  colorPairs.forEach { colors in  let hstack = UIStackView()  hstack.spacing = 8  hstack.distribution = .fillEqually   var v = MyGradientView()  v.colorArray = colors  v.vertical = true  hstack.addArrangedSubview(v)    v = MyGradientView()  v.colorArray = colors  v.vertical = false  hstack.addArrangedSubview(v)    stack.addArrangedSubview(hstack)  }    // a pair of plain, solid color views for comparison  let hstack = UIStackView()  hstack.spacing = 8  hstack.distribution = .fillEqually    var v = UIView()  v.backgroundColor = .systemRed  hstack.addArrangedSubview(v)  v = UIView()  v.backgroundColor = .systemBlue  hstack.addArrangedSubview(v)    stack.addArrangedSubview(hstack)    stack.translatesAutoresizingMaskIntoConstraints = false  view.addSubview(stack)  let g = view.safeAreaLayoutGuide  NSLayoutConstraint.activate([  stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),  stack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),  stack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),  stack.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),  ])    // outline the stack view  // so we can see its frame  let outlineView = UIView()  outlineView.backgroundColor = .clear  outlineView.layer.borderColor = UIColor.black.cgColor  outlineView.layer.borderWidth = 3  outlineView.translatesAutoresizingMaskIntoConstraints = false  view.addSubview(outlineView)  NSLayoutConstraint.activate([  outlineView.topAnchor.constraint(equalTo: stack.topAnchor, constant: -2.0),  outlineView.leadingAnchor.constraint(equalTo: stack.leadingAnchor, constant: -2.0),  outlineView.trailingAnchor.constraint(equalTo: stack.trailingAnchor, constant: 2.0),  outlineView.bottomAnchor.constraint(equalTo: stack.bottomAnchor, constant: 2.0),  ])  }   }  

Результат выполнения этого кода:

введите описание изображения здесь

enter image description here