title: if we're in the real pre-commit handler we can't actually add any new fences due to CA restriction - could this mean something here?
body: <p>I am trying to find why a collection of custom UIButtons does not work. In a version <a href="https://stackoverflow.com/questions/40558939/how-do-i-rotate-a-group-of-buttons-programmatically-in-swift">described in my earlier post</a> I created a circle of UIButtons <a href="https://stackoverflow.com/questions/1378765/how-do-i-create-a-basic-uibutton-programmatically">programmatically</a> in <a href="https://stackoverflow.com/a/19450611/2348597">Swift 3</a> and anchored the circle to the centre of the screen. That version used a subclass of UIView - based on an <a href="https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson5.html" rel="nofollow noreferrer">Apple Swift tutorial</a> (<em>Implement the Button Action</em>) - together with an implementation of autolayout that draws on Imanou Petit’s excellent <a href="https://stackoverflow.com/a/26181982/2348597">code examples</a> (No.6 <em>Anchor</em>). In that version I managed to get my buttons to rotate successfully when the iPhone rotates but the button action-target fails to work. </p>
  
  <p>So I have now tried an alternative version using a viewcontroller instead of a subclass of UIView. This time the same button action-target works but rotating the phone causes the image to shift away from the centre <em>as shown below</em>.</p>
  
  <p><a href="https://i.stack.imgur.com/aJNlZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/aJNlZ.png" alt="enter image description here"></a></p>
  
  <p>With each rotation the following message also appears twice in the debug area of Xcode. </p>
  
  <pre><code>    ***[App] if we're in the real pre-commit handler we can't 
      actually add any new fences due to CA restriction***
  </code></pre>
  
  <p>The message happens three times out of four, i.e. there is no message when the phone is turned upside down. This occurs when I run either the <a href="https://stackoverflow.com/questions/40558939/how-do-i-rotate-a-group-of-buttons-programmatically-in-swift">code in my previous post</a> or the code <em>shown below</em>. And in each case it made no difference whether the Upside Down box was checked or un-checked.</p>
  
  <p><a href="https://i.stack.imgur.com/zNCUG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zNCUG.png" alt="enter image description here"></a>
  I also tried <a href="https://stackoverflow.com/questions/38458170/ios-10-app-if-were-in-the-real-pre-commit-handler-we-cant-actually-add-any/39493900#39493900?newreg=9cbcaefe398d4f83b0df1d011e9e9041">disabling OS_ACTIVITY MODE</a> but that changed nothing except hide a message that might potentially explain the problem.  Someone more experienced than me will hopefully recognise what this debug message means either in the context of my previous code (<a href="https://stackoverflow.com/questions/40558939/how-do-i-rotate-a-group-of-buttons-programmatically-in-swift">shown here</a>) or my latest code, <em>shown below</em>. </p>
  
  <p><strong>ORIGINAL CODE</strong> </p>
  
  <pre><code>import UIKit
  
  class ViewController: UIViewController {
  
  // MARK: Initialization
  
  let points: Int             = 10    // 80 25 16 10  5
  let dotSize: CGFloat        = 60    // 12 35 50 60 99
  let radius: CGFloat         = 48    // 72 70 64 48 42
  var centre: CGPoint?
  
  var arcPoint                = CGFloat(M_PI * -0.5)  // clockwise from 12+ (not 3+)!
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      let myView = UIView()
      myView.translatesAutoresizingMaskIntoConstraints   = false
      view.addSubview(myView)
      centre = centrePoint()
      let horizontalConstraint = myView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
      let verticalConstraint = myView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
      NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
  
      drawUberCircle()
      drawBoundaryCircles()
  
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  func drawUberCircle() {
  
      // Create a CAShapeLayer
  
      let shapeLayer = CAShapeLayer()
  
      // give Bezier path layer properties
      shapeLayer.path = createBezierPath().cgPath
  
      // apply layer properties
      shapeLayer.strokeColor      = UIColor.cyan.cgColor
      shapeLayer.fillColor        = UIColor.cyan.cgColor
      shapeLayer.lineWidth        = 1.0
  
      // add layer
      view.layer.addSublayer(shapeLayer)
  }
  
  func createBezierPath() -&gt; UIBezierPath {
      // create a new path
      let path  = UIBezierPath(arcCenter: centre!,
                               radius: radius * 2.0,
                               startAngle: CGFloat(M_PI * -0.5),
                               endAngle: CGFloat(M_PI * 1.5),
                               clockwise: true)
      return path
  }
  
  func drawBoundaryCircles() {
  
      for index in 1...points {
          let point: CGPoint  = makeBoundaryPoint(centre: centre!)
          drawButton(point: point, index: index)
      }
  }
  
  func makeBoundaryPoint(centre: CGPoint) -&gt; (CGPoint) {
      arcPoint += arcAngle()
      print(arcPoint)
      let point   = CGPoint(x: centre.x + (radius * 2 * cos(arcPoint)), y: centre.y + (radius * 2 * sin(arcPoint)))
      return (point)
  }
  
  func arcAngle() -&gt; CGFloat {
      return CGFloat(2.0 * M_PI) / CGFloat(points)
  }
  
  
  func centrePoint() -&gt; CGPoint {
      return CGPoint(x: view.bounds.midX, y: view.bounds.midY)
  }
  
  func drawButton(point: CGPoint, index: Int) {
      let myButton = UIButton(type: .custom) as UIButton
      myButton.frame              = CGRect(x: point.x - (dotSize/2), y: point.y - (dotSize/2), width: dotSize, height: dotSize)
      myButton.backgroundColor    = UIColor.white
      myButton.layer.cornerRadius = dotSize / 2
      myButton.layer.borderWidth  = 1
      myButton.layer.borderColor  = UIColor.black.cgColor
      myButton.clipsToBounds      = true
      myButton.titleLabel!.font   =  UIFont(name: "HelveticaNeue-Thin", size: dotSize/2)
      myButton.setTitleColor(UIColor.red, for: .normal)
      myButton.setTitle(String(index), for: .normal)
      myButton.tag                = index;
      myButton.sendActions(for: .touchUpInside)
      myButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
      view.addSubview(myButton)
  }
  
  func buttonAction(myButton: UIButton) {
      let sender:UIButton = myButton
      print("Button \(sender.tag) works")
      }
  }
  </code></pre>
  
  <p>I am still in the process of learning Swift so it doesn’t matter at this stage whether the solution uses a viewcontroller or a subclass of UIView so long as I can arrange a circle of UIButtons that still work after I configure them using autolayout. Every suggestion is welcome. Thanks.</p>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>The message that appeared in Xcode’s debug area - and which I used in the subject line of this post - was clearly not the issue. Thanks to Rob Mayoff, NSLayoutConstraint now computes the dimensions and position of each button whereas these were computed prior to run-time in my original code. His solution along with several other improvements are now reflected in the code below. To this I added the original action-target for the buttons. These not only work but remain locked to the centre of the view whenever the device orientation changes. </p>
  
  <p>The code can easily be made to work for a different size configuration by changing values for radius, buttonCount and buttonSideLength (see table). </p>
  
  <p><a href="https://i.stack.imgur.com/z0jK2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/z0jK2.png" alt="enter image description here"></a></p>
  
  <p>Here is the code</p>
  
  <pre><code>import UIKit
  
  class ViewController: UIViewController {
  
  override func viewDidLoad() {
      super.viewDidLoad()
      createUberCircle()
      createButtons()
      }
  
  override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .all }
  
  private let radius: CGFloat = 85
  private let buttonCount = 5
  private let buttonSideLength: CGFloat = 100
  
  private func createUberCircle() {
      let circle = ShapeView()
      circle.translatesAutoresizingMaskIntoConstraints = false
      circle.shapeLayer.path = UIBezierPath(ovalIn: CGRect(x: -radius, y: -radius, width: 2*radius, height: 2*radius)).cgPath
      if buttonCount &lt; 10 {
          circle.shapeLayer.fillColor = UIColor.clear.cgColor
      } else {
          circle.shapeLayer.fillColor = UIColor.cyan.cgColor
          }
      view.addSubview(circle)
      circle.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
      circle.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
      }
  
  private func createButtons() {
      for i in 1 ... buttonCount {
          createButton(number: i)
          }
      }
  
  private func createButton(number: Int) {
      let button = UIButton(type: .custom)
      button.translatesAutoresizingMaskIntoConstraints = false
      button.backgroundColor = .white
      button.layer.cornerRadius = buttonSideLength / 2
      button.layer.borderWidth = 1
      button.layer.borderColor = UIColor.black.cgColor
      button.clipsToBounds = true
      button.titleLabel!.font = UIFont.systemFont(ofSize: buttonSideLength / 2)
      if buttonCount &gt; 25 {
          button.setTitleColor(.clear, for: .normal)
      } else {
          button.setTitleColor(.red, for: .normal)
          }
      button.setTitle(String(number), for: .normal)
      button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
      button.tag = number
  
      view.addSubview(button)
  
      let radians = 2 * CGFloat.pi * CGFloat(number) / CGFloat(buttonCount) - CGFloat.pi / 2
      let xOffset = radius * cos(radians)
      let yOffset = radius * sin(radians)
      NSLayoutConstraint.activate([
          button.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: xOffset),
          button.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: yOffset),
          button.widthAnchor.constraint(equalToConstant: buttonSideLength),
          button.heightAnchor.constraint(equalToConstant: buttonSideLength)
          ])
          }
  
  func buttonAction(myButton: UIButton) {
      let sender:UIButton = myButton
      print("Button \(sender.tag) works")
          }
  
      }
  
  
  class ShapeView: UIView {
      override class var layerClass: Swift.AnyClass { return CAShapeLayer.self }
      lazy var shapeLayer: CAShapeLayer = { self.layer as! CAShapeLayer }()
      }
  </code></pre>