作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发适用于 iOS 的 Xamarin.Forms 应用程序。此应用程序由 UIView
组成,其中包含 CALayers
子层。它们的添加方式如下:
// draw all the pins from the list
foreach (var pin in _control.PinsSource)
{
var point = new CGPoint
{
X = pin.Longitude,
Y = pin.Latitude
};
var shapeLayer = new CAShapeLayer
{
Name = nameof(MapItem),
Path = MakeCircleAtLocation(point, PinRadius).CGPath,
FillColor = UIColor.Red.CGColor
};
Layer.AddSublayer(shapeLayer);
}
// Create a UIBezierPath which is a circle at a certain location of a certain radius.
private static UIBezierPath MakeCircleAtLocation(CGPoint location, nfloat radius)
{
var path = new UIBezierPath();
path.AddArc(location, radius, 0, (float)(Math.PI * 2.0), true);
return path;
}
然后我有一个 UIPinchGestureRecognizer
,它可以缩放 UIView
和其他一些 GestureRecognizers
(如平移)。
缩放和平移基础 View 效果很好。 UIView
使用名为 _currentScale
的变量进行缩放。请参阅此处的完整方法:
private void HandlePinch(UIPinchGestureRecognizer recognizer)
{
// Prevent the object to become too large or too small
var newScale = (nfloat)Math.Max(MinZoomLevel, Math.Min(_currentScale * recognizer.Scale, MaxZoomLevel));
if (_currentScale != newScale)
{
_currentScale = newScale;
Transform = CGAffineTransform.MakeScale(_currentScale, _currentScale);
foreach (var subLayer in Layer.Sublayers)
{
if (subLayer.Name == nameof(MapItem))
subLayer.Transform = CATransform3D.MakeScale(PinRadius / _currentScale, PinRadius / _currentScale, 1);
}
}
recognizer.Scale = 1;
}
如果子图层是 map 图钉,我确实不使用_currentScale
对其进行缩放,因此这就是我使用PinRadius/划分比例的原因_currentScale
。
缩放工作正常,但是图钉在 map 上移动,这很奇怪。请参阅此处:
我该如何解决这个问题?
最佳答案
不幸的是,我找不到另一种方法,然后在每次捏合时重新创建一个新的CAShapeLayer
。虽然很丑陋,但它确实有效。
private void HandlePinch(UIPinchGestureRecognizer recognizer)
{
// Prevent the object to become too large or too small
var newScale = (nfloat)Math.Max(MinZoomLevel, Math.Min(_currentScale * recognizer.Scale, _maxZoomLevel));
if (_currentScale != newScale)
{
_currentScale = newScale;
_currentPinRadius = _pinRadius / _currentScale;
Transform = CGAffineTransform.MakeScale(_currentScale, _currentScale);
// First layer is a CALayer, so start at 1
for (var i = 1; i < Layer.Sublayers.Length; i++)
{
var caLayer = ((CAShapeLayer)Layer.Sublayers[i]);
var cgPoint = new CGPoint
{
X = _control.PinsSource[i - 1].Longitude,
Y = _control.PinsSource[i - 1].Latitude
};
caLayer.Path = CreateCircle(cgPoint, _currentPinRadius);
}
}
recognizer.Scale = 1;
}
关于ios - CATransform3D.MakeScale 正在移动层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51376577/
我是一名优秀的程序员,十分优秀!