I'm trying to disable an implicit animation that is causing the position of my ShapeLayer instance (the small circle at the end of the line) to be animated away from and then back to its location at the end of the line.
A screenshot of the problem is posted here https:// imgur.com/a/I67KjZo
I have tried the approach for using override func action(forKey:) using position as the key, and also the path key. I also tried CATransaction.setDisableActions(true) but that didn't have any apparent effect.
I have been unable to figure out how to solve variations of this problem for almost a month and I would appreciate if someone could help me out here.
When the container (yellow box) is resized, I want its bounds to be animated just as you see here, but I don't want the circle sublayer to "go somewhere else" and come back again just in time for the end of the animation.
Or if disabling an animation is not the best answer here, is there another way I could make the container layer determine the position of its sublayers that won't cause the resize animation disintegrate the arrangement this way?
The full project is here - https://github.com/ddownn/ViewResizeAnimationVariableWidth/tree/master/ViewResizeAnimationVariableWidth
class ContainerView: UIView {
		override class var layerClass: AnyClass { return ContainerLayer.self }
		override func draw(_ rect: CGRect) { }
}
class ContainerLayer: CALayer, CALayerDelegate {
		var circle = ShapeLayer()
		var didSetup = false
		var figureCenter: CGPoint { return CGPoint(x: self.bounds.midX, y: self.bounds.midY) }
		var figureDiameter: CGFloat { return min(self.bounds.width, self.bounds.height) }
		var figureRadius: CGFloat { return figureDiameter / 2 }
		var strokeWidth: CGFloat { return max(round(figureDiameter / 10), 1) }
		var circleDiameter: CGFloat { return max(round(figureDiameter / 25), 5) }
		var circleRadius: CGFloat { return circleDiameter/2 }
		var locRadius: CGFloat { return figureRadius - circleRadius - strokeWidth }
		var circleLineWidth: CGFloat = 1
		var unitLoc: CGPoint { return CGPoint(x: figureCenter.x + cos(-halfPi) * locRadius, y: figureCenter.y + sin(-halfPi) * locRadius) }
		override func layoutSublayers() {
				super.layoutSublayers()
				... setup
				updateCircleBounds()
		}
		func setup() {
				...
				self.needsDisplayOnBoundsChange = true
		}
		func updateCircleBounds() {
				self.circle.bounds = CGRect(x: 0, y: 0, width: circleDiameter, height: circleDiameter)
				self.circle.position = unitLoc
				self.circle.updatePath()
		}
		override func draw(in ctx: CGContext) {
				 ... stroke ctx paths, etc
		}
}
class ShapeLayer: CAShapeLayer {
		var didSetup = false
		var diameter: CGFloat { return self.bounds.width }
		var pathOrigin: CGPoint { return CGPoint(x: self.bounds.minX, y: self.bounds.minY) }
		var pathSize: CGSize {return CGSize(width: self.diameter, height: self.diameter) }
		var strokeWidth: CGFloat?
		var fColor: CGColor?
		var sColor: CGColor?
		override func layoutSublayers() {
				super.layoutSublayers()
				... setup
				updatePath()
		}
		override func action(forKey key: String) -> CAAction? {
				print(key)
				if key == #keyPath(position) {
						if self.value(forKey:"suppressPositionAnimation") != nil {
								print("key: \(key)")
								return nil
						}
				}
				return super.action(forKey:key)
		}
		func setup() {
				...
				self.setValue(true, forKey:"suppressPositionAnimation")
		}
		func updatePath() {
				self.path = UIBezierPath(ovalIn: CGRect(origin: pathOrigin, size: pathSize).insetBy(dx: self.lineWidth/2, dy: self.lineWidth/2)).cgPath
		}
}
Post
Replies
Boosts
Views
Activity
Trying to work through Apple's "View Programming Guide for iOS" and in the section Embedding Layer Objects in a View I came up with this translation.But with myLayer = CGImage I get an error "Cannot assign value of type 'CGImage' to type 'CALayer'" and with let viewBounds = backingView.bounds an error "Use of unresolved identifier 'backingView'"I get that the guide is pretty old but what should I do to make this work the way it's supposed to? I would really appreciate any advice.class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create the layer
var myLayer = CALayer()
// Set the contents of the layer to a fixed image. And set
// the size of the layer to match the image size.
let layerContents = UIImage(named: "myImage")
let imageSize = layerContents?.size
myLayer.bounds = CGRect(x: 0, y: 0, width: imageSize?.width ?? 0.0, height: imageSize?.height ?? 0.0)
if let CGImage = layerContents?.cgImage {
myLayer = CGImage // Error "Cannot assign value of type 'CGImage' to type 'CALayer'"
}
// Add the layer to the view.
let viewLayer = view.layer
viewLayer.addSublayer(myLayer)
// Center the layer in the view.
let viewBounds = backingView.bounds // Error "Use of unresolved identifier 'backingView'"
myLayer.position = CGPoint(x: viewBounds.midX, y: viewBounds.midY)
}
}This is the actual code listing from the guide:- (void)viewDidLoad {
[super viewDidLoad];
// Create the layer.
CALayer* myLayer = [[CALayer alloc] init];
// Set the contents of the layer to a fixed image. And set
// the size of the layer to match the image size.
UIImage layerContents = [[UIImage imageNamed:@"myImage"] retain];
CGSize imageSize = layerContents.size;
myLayer.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
myLayer = layerContents.CGImage;
// Add the layer to the view.
CALayer* viewLayer = self.view.layer;
[viewLayer addSublayer:myLayer];
// Center the layer in the view.
CGRect viewBounds = backingView.bounds;
myLayer.position = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds));
// Release the layer, since it is retained by the view's layer
[myLayer release];
}
In an Xcode workspace, I'm trying to add playground support for custom classes within the project for a playground within the same workspace.I followed all the steps in this post https://useyourloaf.com/blog/adding-playgrounds-to-xcode-projects/but I don't see Cocoa Touch Framework in the template list when going to File > New > Target. I thought it should be at the bottm in "Framework & Library"I tried just adding the one called Framework but when in the playground I "import frameworkName" I get an error about how it can't find the module.
Is there some reason that I won't be able to use "Connect via Network" in Xcode 11.2.1 to debug an iPhone 5c which has iOS 10.3.3 installed?It works fine with my iPhone 7 Plus which has iOS 13.2.3. But with the iPhone 5c, there is no checkbox for "Connect via Network"Both phones and the computer are connected to the same wifi, and all devices are logged in to the same Apple ID.I am able to install and run apps to the iPhone 5c using the USB cable without any problems.Edited with additional information:I have tried it in Xcode 10 & 11 in Catalina, and also Xcode 9 & 10 in High Sierra.I tried to follow the steps found in a reply to this thread: https://forums.developer.apple.com/thread/89040Specifically, I disabled the iPhone's network entirely, connected it over USB, looked for a "connect via network" option, connected the iPhone to the same network as the computer, looked for the "connect via network" option, it never appears. But I can never get the line to show up that should say "Connect via Network", it's missing entirely for this device only, not simply grayed out. I've also tried un-pairing/re-pairing the device.I'm starting to think that maybe the iPhone 5c is simply incompatible with this connect via network feature, but I don't know if this is true, so I'm hoping someone could let me know.