Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edge offsets (.top(x), .bottom(x), .start(x), .end(x)) aren't used in autoSizeThatFits #276

Open
constantine-fry opened this issue Nov 27, 2023 · 1 comment

Comments

@constantine-fry
Copy link

constantine-fry commented Nov 27, 2023

hi Luc,

Thanks for working on such a great framework. It's hard to find a layout framework that doesn't use auto layout these days.

I was testing your frameworks and came across one issues. The framework calculates incorrect intrinsic size for a view that uses edge pins such as (.top, .bottom, .start, .end).

For instance, I wanted to make the following layout:

Screenshot 2023-11-27 at 21 14 02

The red line represents the bounding box of the view controller. The black line represents the bounding box of the view with the content. The demonstration purposes I used two black boxes as content.

I wrote the following code:

private final class ViewController: UIViewController {

  private let cellView: TestCellView

  init() {
    self.cellView = TestCellView()
    cellView.layer.borderColor = UIColor.black.cgColor
    cellView.layer.borderWidth = 1
    super.init()
  }

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

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = .white
    self.view.addSubview(cellView)
  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let size = cellView.sizeThatFits(self.view.bounds.size)
    cellView.frame = CGRectMake(0, view.bounds.height / 2 - size.height / 2, size.width, size.height)
  }
}

private final class TestCellView: UIView {
  
  private let view1: UIView
  private let view2: UIView
  
  init() {
    self.view1 = UIView()
    self.view2 = UIView()
    
    super.init(frame: .zero)
    
    self.view1.backgroundColor = .black
    self.view2.backgroundColor = .black
    
    self.addSubview(view1)
    self.addSubview(view2)
  }
  
  required init?(coder: NSCoder) {
    fatalError()
  }
  
  override func layoutSubviews() {
    super.layoutSubviews()
    self.performPinLayout()
  }
  
  private func performPinLayout() {
    view1.pin
      .size(CGSize(width: 50, height: 50))
      .start(16)
      .top(16)
      .bottom(16)
    
    view2.pin
      .size(CGSize(width: 50, height: 50))
      .top(16)
      .end(16)
      .bottom(16)
  }
  
  override func sizeThatFits(_ size: CGSize) -> CGSize {
    autoSizeThatFits(size, layoutClosure: performPinLayout)
  }
}

The framework made the following layout:
Screenshot 2023-11-27 at 21 14 22

Note two issues:

  1. there is a gap between red and black lines on the right side of the image.
  2. there is no margin at the bottom of the boxes.

I assume it happens because PEdgeInsets is created without _top, _bottom, _left and _right values.
https://github.com/layoutBox/PinLayout/blob/master/Sources/Impl/PinLayout%2BLayouting.swift#L138

Let me know if you need additional input from me.

Thanks,
C.

@lucdion
Copy link
Member

lucdion commented Dec 12, 2023

Hi @constantine-fry, sorry that you have encountered an issue. If you have the time, you are welcome to submit a Pull request that fixes this possible issue, it would be a pleasure to review it. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants