2016-09-19 4 views
2

저는 iMessage 응용 프로그램을 사용하여 프로그래밍 방식으로보기를 추가했습니다. 그러나 나는 항상 올바른 크기로 만들기위한 올바른 제약 조건을 해결할 수 없습니다. 예를 들어 확장 프로그램을 다른 버전으로두고 다시 돌아 오는 경우보기가 수백 px 아래로 이동합니다. 나는 이것이 .isActive와 관련이 있다고 생각한다. 내 목표는 뷰를 자동으로 크기를 조정하여 항상 올바른 크기로 만들거나 사용 가능한 전체 높이와 너비를 차지하는 것입니다.신속하게 전체 크기보기를 프로그래밍 방식으로 추가하십시오.

func createBrowser() { 
    let controller = MSStickerBrowserViewController(stickerSize: .small) 
    addChildViewController(controller) 
    view.addSubview(controller.view) 

    controller.view.translatesAutoresizingMaskIntoConstraints = false 
    controller.stickerBrowserView.backgroundColor = UIColor.blue 
    controller.stickerBrowserView.dataSource = self 

    view.topAnchor.constraint(equalTo: controller.view.topAnchor).isActive = true 
    view.bottomAnchor.constraint(equalTo: controller.view.bottomAnchor).isActive = true 
    view.leftAnchor.constraint(equalTo: controller.view.leftAnchor).isActive = true 
    view.rightAnchor.constraint(equalTo: controller.view.rightAnchor).isActive = true 
    view.centerXAnchor.constraint(equalTo: controller.view.centerXAnchor).isActive = true 
    view.centerYAnchor.constraint(equalTo: controller.view.centerYAnchor).isActive = true 
} 

스크린 샷 : https://d17oy1vhnax1f7.cloudfront.net/items/1F2B0s3v0s1k3E2L0Z07/Screen%20Shot%202016-09-19%20at%2011.42.51%20AM.png

+0

이 바보 같은 질문이 될 수있다/내가 제대로 코드를 읽는되지 않을 수 있습니다하지만 당신이 귀하의 제약 조건을 잘못 잡았습니까? 이전 뷰에 대한 제약 조건을 기반으로 새 뷰에 대한 제약 조건을 설정하지 않아야합니까? 새로운 자식 컨트롤러의 뷰를 기반으로 부모 컨트롤러의 뷰에 대한 제약 조건을 설정하는 것처럼 보입니다. – Sparky

+0

@ Sparky 이런 뜻인가요? controller.view.topAnchor.constraint (equalTo : view.topAnchor) .isActive = true입니다. 나는 그것을했고 그 행동은 똑같다. –

+0

@ Sparky? 죄송합니다, 저는 iOS 개발자에게 상대적으로 새로운입니다. 릴 도와 줘? 감사! –

답변

0

하는 것이 더 나은 내가 다음 조립 한 것을 설명하기. 이 방법은 하위 뷰 레이아웃을 수정하는 두 가지 방법을 보여줍니다. 제약 조건을 사용할 때, 제약 조건을 배열로 생성하고 한 번에 모두 활성화하는 것을 선호합니다. createredSquareWithConstraints 코드에서 볼 수 있습니다. 제약 조건은 한 관점의 특징을 다른 관점의 특성과 관련시키는 단순한 선형 방정식입니다. 예를 들어 "pseudocode"에서 배열의 첫 번째 제약 조건은 다음과 같이 쓸 수 있습니다.

"컨테이너 뷰의 선행 마진의 1 배에 0을 더한 값과 동일한 서브 뷰의 선행 마진을 설정합니다.

(당신은 그것의 파단 중 하나의 특성에 따라 포함하는 뷰의 제약 조건을 설정하는 것처럼 그것이 나에게 보였다 나는 이전에 혼란스러워지고 한 이유입니다.)

이 레이아웃을 사용하는 것이 완벽하게 유효하지만 제약 조건, 나는 선호하는 방법론 요즘은 viewWillTransitionToSize() delegate 메소드를 오버라이드하는 것으로 생각합니다.이 메소드는 포함 된 뷰의 크기를 지정하면 뷰 컨트롤러의 서브 뷰의 프레임을 지정해야합니다. 따라서, 이것도 구현해 보았습니다. 초기 프레임이있는 노란색 사각형을 만들고 viewWillTransitionToSize가 호출 될 때마다 수정됩니다. 필자는 개인적으로 레이아웃 제약 조건을 사용하는 것보다 훨씬 덜 까다롭게 느껴진다.

버튼으로 배치하고 화면을 회전하면 두 방법 모두 동일한 결과가 나타납니다. [주의 : 나는 하나의 사각형을 제약 된 것으로 표시하고 하나는 제약되지 않은 것으로 표시했다. 그러나 현실적으로 그들은 모두 다른 방식으로 제한되어있다. 나는 이것이 당신이 실제로 어떻게 할 것인가는 분명하지 않다는 것을 추가 할 것입니다 - 당신은 하나의 방법론을 선택해야하고 그렇지 않으면 당신의 코드는 모든 곳에서있을 것입니다!].

희망 하시겠습니까?

import UIKit 

class ViewController: UIViewController { 

    var constrainedredSquare : UIView! 
    var unconstrainedRedSquare : UIView! 
    var methodOneButton : UIButton! 
    var methodTwoButton : UIButton! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     self.view.backgroundColor = UIColor.blue 

     func getButton(name: String) -> UIButton { 
      let button : UIButton = UIButton() 
      button.backgroundColor = UIColor.white 
      button.layer.cornerRadius = 3 
      button.clipsToBounds = true 
      button.setTitle(name, for: UIControlState.normal) 
      button.setTitleColor(UIColor.black, for: UIControlState.normal) 
      return button 
     } 

     self.methodOneButton = getButton(name: "Red - Constraints") 
     self.methodTwoButton = getButton(name: "Yellow - viewWillTransitionToSize") 

     self.methodOneButton.addTarget(self, action: #selector(self.createRedSquareWithConstraints), for: .touchUpInside) 
     self.methodTwoButton.addTarget(self, action: #selector(self.createYellowSquareWithoutConstraints), for: .touchUpInside) 
     self.methodOneButton.frame = CGRect(origin: CGPoint(x: 200, y: 100), size: CGSize(width: 300, height: 300)) 
     self.methodTwoButton.frame = CGRect(origin: CGPoint(x: self.view.frame.width - 500, y: 100), size: CGSize(width: 300, height: 300)) 
     self.view.addSubview(self.methodOneButton) 
     self.view.addSubview(self.methodTwoButton) 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
     if let _ = self.unconstrainedRedSquare { 
      self.unconstrainedRedSquare.frame = CGRect(origin: CGPoint.zero, size: size) 
     } 
     self.methodOneButton.frame = CGRect(origin: CGPoint(x: 200, y: 100), size: CGSize(width: 300, height: 300)) 
     self.methodTwoButton.frame = CGRect(origin: CGPoint(x: size.width - 500, y: 100), size: CGSize(width: 300, height: 300)) 
    } 


    func createYellowSquareWithoutConstraints() { 
     if let _ = self.unconstrainedRedSquare { 
      self.unconstrainedRedSquare.removeFromSuperview() 
     } 
     else 
     { 
      if let _ = constrainedredSquare { 
       self.constrainedredSquare.removeFromSuperview() 
      } 
      self.unconstrainedRedSquare = UIView() 
      self.unconstrainedRedSquare.backgroundColor = UIColor.yellow 
      self.unconstrainedRedSquare.frame = CGRect(origin: CGPoint.zero, size: self.view.frame.size) 
      self.view.addSubview(self.unconstrainedRedSquare) 

      self.view.bringSubview(toFront: self.methodOneButton) 
      self.view.bringSubview(toFront: self.methodTwoButton) 
     } 

    } 

    func createRedSquareWithConstraints() { 
     if let _ = self.constrainedredSquare { 
      self.constrainedredSquare.removeFromSuperview() 
     } 
     else 
     { 
      if let _ = self.unconstrainedRedSquare { 
       self.unconstrainedRedSquare.removeFromSuperview() 
      } 
      let redSquare : UIView = UIView() 
      redSquare.backgroundColor = UIColor.red 

      self.view.addSubview(redSquare) 

      self.view.bringSubview(toFront: self.methodOneButton) 
      self.view.bringSubview(toFront: self.methodTwoButton) 

      let rsConstraints : [NSLayoutConstraint] = [NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.leading, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.trailing, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.top, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.bottom, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.width, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.height, multiplier: 1.0, constant: 0)] 
      redSquare.translatesAutoresizingMaskIntoConstraints = false 
      NSLayoutConstraint.activate(rsConstraints) 
     } 
    } 
} 
0

내 전화 번호는 UIView입니다. 그것은 (당신이 원하는 경우에만) 어떤 측면에 여분의 패딩을 추가 할 수 있습니다 :

public extension UIView { 
    typealias ConstraintsTupleStretched = (top:NSLayoutConstraint, bottom:NSLayoutConstraint, leading:NSLayoutConstraint, trailing:NSLayoutConstraint) 
    func addSubviewStretched(subview:UIView?, insets: UIEdgeInsets = UIEdgeInsets()) -> ConstraintsTupleStretched? { 
     guard let subview = subview else { 
      return nil 
     } 

     subview.translatesAutoresizingMaskIntoConstraints = false 
     addSubview(subview) 

     let constraintLeading = NSLayoutConstraint(item: subview, 
                attribute: .Left, 
                relatedBy: .Equal, 
                toItem: self, 
                attribute: .Left, 
                multiplier: 1, 
                constant: insets.left) 
     addConstraint(constraintLeading) 

     let constraintTrailing = NSLayoutConstraint(item: self, 
                attribute: .Right, 
                relatedBy: .Equal, 
                toItem: subview, 
                attribute: .Right, 
                multiplier: 1, 
                constant: insets.right) 
     addConstraint(constraintTrailing) 

     let constraintTop = NSLayoutConstraint(item: subview, 
               attribute: .Top, 
               relatedBy: .Equal, 
               toItem: self, 
               attribute: .Top, 
               multiplier: 1, 
               constant: insets.top) 
     addConstraint(constraintTop) 

     let constraintBottom = NSLayoutConstraint(item: self, 
                attribute: .Bottom, 
                relatedBy: .Equal, 
                toItem: subview, 
                attribute: .Bottom, 
                multiplier: 1, 
                constant: insets.bottom) 
     addConstraint(constraintBottom) 
     return (constraintTop, constraintBottom, constraintLeading, constraintTrailing) 
    } 

} 

사용법 :

view.addSubviewStretched(tableView) 

let BorderedBackgroundInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1) 
view?.addSubviewStretched(calendar.view, insets: BorderedBackgroundInset) 
+0

신속성의 최신 버전을 충족시키기 위해 제약 조건에서 코드를 조정해야했지만 완벽하게 작동했습니다. 감사합니다! –

+0

이 메시지 받기 "addSubvieStretched (subview : insets :) '호출 결과가 사용되지 않습니다.그게 무슨 뜻이야? –

+0

위의 URL을 사용하여 생성 된 오류의 더 좋은 스크린 샷은 다음과 같습니다. https://www.dropbox.com/s/8gi67ulcjuldm4k/Screenshot%202016-10-05%2012.24.48.png?dl=0 및 https ://www.dropbox.com/s/t9ks7d02coycicb/Screenshot%202016-10-05%2012.26.34.png?dl=0 –

관련 문제