Hi
Thanks for the reply. I've done a clean build and deleted the files and folders in the derived data folder and installed GM 2 ssed and rebooted the Mac. I read the release notes for the GM 2 seed and saw a similar error under the Reality Composer heading, but the suggested workaround didn't really apply even though I did "manually" link my custom framework as a binary in the build phrase.
With that said, here is code that will crash the device but run ok on the simulator:
let storyboard = UIStoryboard(name: "Verification", bundle: nil)
let slideViewController = storyboard.instantiateViewController(withIdentifier: "Slide") as! SlideTableViewController
The code to SlideTableViewController:
import VerifyKit
import UIKit
class SlideTableViewController: UIViewController {
// MARK: Instance Properties
/// The heights of the slide view.
let closedHeight: CGFloat = UIApplication.shared.keyWindow!.safeAreaInsets.bottom + 90
let openHeight: CGFloat = UIApplication.shared.keyWindow!.frame.height - UIApplication.shared.keyWindow!.safeAreaInsets.top - 140
/// The mid point between the `closedHeight` and `openHeight` of the slide view.
lazy var midPoint = (openHeight + closedHeight) / 2
/// The sticky points to which the slide view should snap to.
lazy var middleStickyPoints: [CGFloat] = [midPoint]
/// The sorted array of all sticky points, including `closedHeight` and `openHeight`.
lazy var allStickyPoints = ([closedHeight, openHeight] + middleStickyPoints).sorted()
/// The transaction.
var transaction: PendingTransaction?
/// The data to display in the slide table view.
private var dataToDisplay: [(title: String, body: String)]?
/// The bottom cosntraint of the slide view to animate.
lazy var bottomConstraint = view.superview!.bottomAnchor.constraint(equalTo: view.topAnchor, constant: closedHeight)
/// The grip bar.
let gripBar = UIView()
/// The close button.
let closeButton = UIButton()
/// The dim view.
let dimView = UIView()
/// The parent view controller.
lazy var parentVC = parent as! ChallengeViewController
/// The open state of the slide view.
var isOpen: Bool = false {
didSet {
if isOpen {
// Move approve/deny buttons to top of screen.
parentVC.buttonCollectionViewConstraint.constant = openHeight - UIApplication.shared.keyWindow!.safeAreaInsets.bottom + 20
} else {
// Move approve/deny buttons to bottom of screen.
parentVC.buttonCollectionViewConstraint.constant = 110
}
}
}
// MARK: Control References
@IBOutlet var previewLabel: UILabel!
@IBOutlet var tableView: UITableView!
// MARK: View functions and events
/// Called after the controller's view is loaded into memory.
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// Hide the last separator line by adding a footer view.
tableView.tableFooterView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 0, height: 1)))
// Pan the slide view.
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panSlideView))
view.addGestureRecognizer(panGestureRecognizer)
// Activate slide table view constraints.
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([tableView.widthAnchor.constraint(equalTo: view.widthAnchor),
tableView.heightAnchor.constraint(equalToConstant: openHeight - 26),
tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 26)])
// Display the grip bar.
gripBar.layer.cornerRadius = 3
view.addSubview(gripBar)
// Activate grip bar constraints.
gripBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([gripBar.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
gripBar.centerXAnchor.constraint(equalTo: view.centerXAnchor),
gripBar.heightAnchor.constraint(equalToConstant: 6),
gripBar.widthAnchor.constraint(equalToConstant: 42)])
// Display the close button.
closeButton.setImage(UIImage(named: "Close")?.withRenderingMode(.alwaysTemplate), for: .normal)
closeButton.layer.cornerRadius = 16
closeButton.addTarget(self, action: #selector(closeSlideView), for: .touchUpInside)
view.addSubview(closeButton)
// Activate close button constraints.
closeButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([closeButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
view.trailingAnchor.constraint(equalTo: closeButton.trailingAnchor, constant: 16),
closeButton.widthAnchor.constraint(equalToConstant: 32),
closeButton.heightAnchor.constraint(equalToConstant: 32)])
}
/// Notifies the view controller that its view is about to be added to a view hierarchy.
/// - parameter animated: If true, the view is being added to the window using an animation.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Set up dim view.
dimView.frame = view.bounds
dimView.backgroundColor = ThemeManager.shared.current.dimBackgroundColor
parentVC.view.insertSubview(dimView, belowSubview: parentVC.buttonCollectionView)
// Activate slide view constraints.
view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([bottomConstraint,
view.leadingAnchor.constraint(equalTo: view.superview!.leadingAnchor),
view.trailingAnchor.constraint(equalTo: view.superview!.trailingAnchor),
view.bottomAnchor.constraint(equalTo: view.superview!.bottomAnchor)])
// Get the table representation of the transaction data.
dataToDisplay = transaction?.tableRepresentation
// Set the preview label's text to the transaction's type.
if let type = transaction?.additionalData[.type] {
previewLabel.text = "\(type.capitalized) \(String.localize("ChallengeInfo"))"
}
}
/// Called when the user taps the `closeButton`.
@objc func closeSlideView() {
animateSlideView(to: allStickyPoints[0])
}
/// Handles the pan gestures on the slide view to animate its states.
/// - parameter recognizer: The gesture recognizer of the pan event.
@objc func panSlideView(_ recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .changed:
let translation = recognizer.translation(in: view)
let panPosition = bottomConstraint.constant - translation.y
// Restrict the pan between `closedHeight` and `openHeight`.
if panPosition > closedHeight, panPosition < openHeight {
bottomConstraint.constant = panPosition
recognizer.setTranslation(.zero, in: view)
}
case .ended:
// Animate the slide view.
let velocity = recognizer.velocity(in: view)
animateSlideView(with: velocity.y)
default:
break
}
}
/// Handles the animations of the slide view to its closest sticky point.
/// - parameter velocity: The velocity the slide view was released with.
private func animateSlideView(with velocity: CGFloat) {
let velocityThreshold: CGFloat = 300
var closestIndex = allStickyPoints.closestIndex(to: bottomConstraint.constant)!
if velocity < -velocityThreshold {
// Swipe up velocity threshold exceeded, snap to next sticky point.
closestIndex = min(allStickyPoints.count - 1, closestIndex + 1)
} else if velocity > velocityThreshold {
// Swipe down velocity threshold exceeded, snap to previous sticky point.
closestIndex = max(0, closestIndex - 1)
}
// Animate the slide view's bottom constraint to its closest sticky point index.
animateSlideView(to: allStickyPoints[closestIndex])
}
/// Handles the animations of the slide view to the given sticky point index.
/// - parameter point: The point to animate the slide view to.
private func animateSlideView(to point: CGFloat) {
isOpen = point == allStickyPoints.last
let transitionAnimator = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.75, animations: {
self.bottomConstraint.constant = point
self.view.superview!.layoutIfNeeded()
})
transitionAnimator.startAnimation()
}
/// Returns the fraction completed by the slide view between the given `start` and `end` points, based on the slide view's current position.
/// - parameter start: The starting point.
/// - parameter end: The ending point.
func fractionCompleteBySlideView(from start: CGFloat, to end: CGFloat) -> CGFloat {
return (bottomConstraint.constant - start) / (end - start)
}
/// Called to notify the view controller that its view has just laid out its subviews.
override func viewDidLayoutSubviews() {
// Animates the `closeButton` and `dimView` opacity.
closeButton.alpha = fractionCompleteBySlideView(from: closedHeight, to: midPoint)
dimView.alpha = fractionCompleteBySlideView(from: midPoint, to: openHeight)
// Animates the `tableView` and `previewLabel` opacity.
tableView.alpha = fractionCompleteBySlideView(from: closedHeight, to: midPoint)
previewLabel.alpha = fractionCompleteBySlideView(from: midPoint, to: closedHeight)
// Animate roundness of top left and top right corners.
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
view.layer.cornerRadius = 16 * fractionCompleteBySlideView(from: closedHeight, to: openHeight)
}
}
The reference to PendingTransaction class is located in VerifyKit framework. I can't understand why this view controller fails but others are display ok in both devive and simulator.
Appreciate the help
Craig