если мы находимся в реальном обработчике предварительной фиксации, мы не можем добавить какие-либо новые заборы из-за ограничений CA - может ли это что-то значить здесь?

Я пытаюсь выяснить, почему не работает коллекция пользовательских кнопок UIB. В версииописано в моем предыдущем посте Я создал круг UIButtonsпрограммно вСвифт 3 и привязал круг к центру экрана. Эта версия использовала подкласс UIView - на основеApple Swift, учебник (Реализуйте действие кнопки) - вместе с реализацией autolayout, которая опирается на превосходный Imanou Petitпримеры кода (No.6анкер). В этой версии мне удалось заставить мои кнопки успешно вращаться, когда iPhone вращается, но кнопка action-target не работает.

Итак, я попробовал альтернативную версию, используя viewcontroller вместо подкласса UIView. На этот раз работает та же кнопка action-target, но при повороте телефона изображение смещается от центракак показано ниже.

С каждым поворотом следующее сообщение также появляется дважды в области отладки XCode.

    ***[App] if we're in the real pre-commit handler we can't 
    actually add any new fences due to CA restriction***

Сообщение появляется три раза из четырех, то есть, когда телефон перевернут вверх дном, сообщения нет. Это происходит, когда я запускаюкод в моем предыдущем посте или кодпоказано ниже, И в каждом случае не имело значения, был ли установлен флажок «Перевернутый вниз» или нет.

Я тоже пробовалотключение OS_ACTIVITY MODE но это ничего не изменило, кроме как скрыть сообщение, которое потенциально может объяснить проблему. Кто-то более опытный, чем я, надеюсь, поймет, что означает это сообщение отладки в контексте моего предыдущего кода (показано здесь) или мой последний код,показано ниже.

ОРИГИНАЛЬНЫЙ КОД

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() -> 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) -> (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() -> CGFloat {
    return CGFloat(2.0 * M_PI) / CGFloat(points)
}


func centrePoint() -> 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")
    }
}

Я все еще нахожусь в процессе изучения Swift, поэтому на данном этапе не имеет значения, использует ли решение viewcontroller или подкласс UIView, если я могу организовать круг UIButton, которые все еще работают после того, как я сконфигурировал их с помощью autolayout. Любое предложение приветствуется. Благодарю.

РЕШЕНИЕ

Сообщение, которое появилось в области отладки XCode - и которое я использовал в строке темы этого поста - явно не было проблемой. Благодаря Робу Мейоффу NSLayoutConstraint теперь вычисляет размеры и положение каждой кнопки, тогда как они были вычислены до времени выполнения в моем исходном коде. Его решение вместе с рядом других улучшений теперь отражено в приведенном ниже коде. К этому я добавил оригинальную цель-действие для кнопок. Они не только работают, но и остаются заблокированными в центре обзора при изменении ориентации устройства.

Код можно легко настроить для работы с конфигурацией другого размера, изменив значения радиуса, buttonCount и buttonSideLength (см. Таблицу).

Вот код

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 < 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 > 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 }()
    }

Ответы на вопрос(2)

Ваш ответ на вопрос