gpt4 book ai didi

ios - Swift:为什么在 touchesBegan() 中将 UIView 的帧大小引用为 (0.0, 0.0)?

转载 作者:行者123 更新时间:2023-11-29 01:14:30 25 4
gpt4 key购买 nike

我只是想在一个愚蠢的 iOS 应用程序中进行一个简单的实验,我想在其中绘制轴作为引用,而可拖动的 UIImageView移动到 UIView .问题是我什么时候可以 touchesBegan()方法,引用UIView在其上绘制轴的框架大小为 (0.0, 0.0),我收到此错误:

Feb 14 08:44:08 Fishmeter[30272] <Error>: CGContextSetRGBStrokeColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

这是我的可拖动代码 UIImageView :

class PinImageView: UIImageView {
var viewForAxis:AxisView!

...
init(imageIcon: UIImage?, location:CGPoint, father:UIImageView, name:String, axisView:AxisView) {
...
self.viewForAxis = axisView
print(self.viewForAxis.frame.size)
...
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch: UITouch = touches.first {
print(self.viewForAxis.frame.size)
self.viewForAxis.hidden = false
self.viewForAxis.pin = self
//self.viewForAxis.setNeedsDisplay()
self.viewForAxis.drawAxis(CGPointMake(self.center.x, self.viewForAxis.frame.origin.y), to: (CGPointMake(self.center.x, self.viewForAxis.frame.origin.y + self.viewForAxis.frame.height)))

}
}
}

第一个print()我得到 (303.0, 414.0)在里面touchesBegan()它变成(0.0, 0.0)然后我得到那个错误。而类AxisView是:

class AxisView: UIView {

var pin:PinImageView?

func drawAxis(from:CGPoint, to:CGPoint) {
let context = UIGraphicsGetCurrentContext()
switch (self.pin!.id) {
case "redPinA","redPinB":
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0)
break
case "bluePinA, bluePinB":
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 1.0, 1.0)
break
default: break
}

/* line width of axes */
CGContextSetLineWidth(context, 0.5)

/* draw vertical axis inside magnifier */
CGContextMoveToPoint(context, from.x, from.y)
CGContextAddLineToPoint(context, to.x, to.y)

/* draw horizontal axis inside magnifier */
//CGContextMoveToPoint(context, self.zoomedPoint!.x - (self.frame.size.width / 2), self.zoomedPoint!.y)
//CGContextAddLineToPoint(context, self.zoomedPoint!.x + (self.frame.size.width / 2), self.zoomedPoint!.y)
CGContextStrokePath(context)
}

/*override func drawRect(rect: CGRect) {
if (pin != nil) {
self.drawAxis(CGPointMake((self.pin?.center.x)!, self.frame.origin.y), to: CGPointMake(self.pin!.center.x, self.frame.origin.y + self.frame.height))
}
}*/

}

正确的做法是什么?正如您从评论中看到的那样,我还尝试将所有内容都放在 drawRect() 中。方法但setNeedsDisplay()未被调用,因为大小为 (0.0, 0.0)...谢谢大家。

这是我在主视图 Controller 中所做的:

self.view.addSubview(self.axisView)
self.axisView.hidden = true

self.redPinA = PinImageView(imageIcon: UIImage(named: "icons/red_pin.png"), location: CGPointMake(40, 110), father: self.imageView, name: "redPinA", axisView: self.axisView)

self.redPinB = PinImageView(imageIcon: UIImage(named: "icons/red_pin.png"), location: CGPointMake(80, 110), father: self.imageView, name: "redPinB", axisView: self.axisView)

self.bluePinA = PinImageView(imageIcon: UIImage(named: "icons/blue_pin.png"), location: CGPointMake(200, 110), father: self.imageView, name: "bluePinA", axisView: self.axisView)

self.bluePinB = PinImageView(imageIcon: UIImage(named: "icons/blue_pin.png"), location: CGPointMake(240, 110), father: self.imageView, name: "bluePinB", axisView: self.axisView)

self.view.addSubview(self.redPinA)
self.view.addSubview(self.redPinB)
self.view.addSubview(self.bluePinA)
self.view.addSubview(self.bluePinB)

最佳答案

该错误正确地指出 touchesBegan 正在调用 drawAxis,它正在调用 CGContext 函数,但您不在有效上下文(因此,“无效上下文 0x0”)。

您不应该直接从 touchesBegan 调用任何 CGContext 函数。您可以更新状态变量,然后调用 setNeedsDisplay,这将导致操作系统调用 drawRect,您可以在其中绘制坐标轴。但不要试图自己画它们。

但我尝试了以下方法并且效果很好:

class AxisView: UIView {

var pin:PinImageView?

func drawAxis(from:CGPoint, to:CGPoint) {
let context = UIGraphicsGetCurrentContext()
switch pin!.id {
case "redPinA", "redPinB":
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0)
case "bluePinA", "bluePinB":
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 1.0, 1.0)
default: break
}

/* line width of axes */
CGContextSetLineWidth(context, 0.5)

/* draw vertical axis inside magnifier */
CGContextMoveToPoint(context, from.x, from.y)
CGContextAddLineToPoint(context, to.x, to.y)

/* draw horizontal axis inside magnifier */
CGContextStrokePath(context)
}

override func drawRect(rect: CGRect) {
if pin != nil {
drawAxis(CGPointMake(pin!.center.x, frame.origin.y), to: CGPointMake(pin!.center.x, frame.origin.y + frame.height))
}
}

}


class PinImageView: UIImageView {

var lastLocation:CGPoint!
var id:String!
var viewForAxis:AxisView!

init(imageIcon: UIImage?, location:CGPoint, name:String, axisView:AxisView) {

super.init(image: imageIcon)
lastLocation = location
id = name

viewForAxis = axisView
print(viewForAxis.frame.size)
center = location
frame = CGRect(x: location.x, y: location.y, width: 40.0, height: 60.0)

userInteractionEnabled = true
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let _ = touches.first {
print(viewForAxis.frame.size)
viewForAxis.hidden = false
viewForAxis.pin = self
viewForAxis.setNeedsDisplay()
}
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
viewForAxis.hidden = true
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch: UITouch = touches.first {
center = touch.locationInView(superview)
viewForAxis.setNeedsDisplay()
}
}

}

class ViewController: UIViewController {

var axisView: AxisView!
var redPinA: PinImageView!
var redPinB: PinImageView!
var bluePinA: PinImageView!
var bluePinB: PinImageView!

override func viewDidLoad() {
super.viewDidLoad()

axisView = AxisView()
axisView.frame = view.bounds
axisView.backgroundColor = UIColor.clearColor()

view.addSubview(axisView)
axisView.hidden = true

redPinA = PinImageView(imageIcon: UIImage(named: "red_pin.png"), location: CGPointMake(40, 110), name: "redPinA", axisView: axisView)

redPinB = PinImageView(imageIcon: UIImage(named: "red_pin.png"), location: CGPointMake(80, 110), name: "redPinB", axisView: axisView)

bluePinA = PinImageView(imageIcon: UIImage(named: "blue_pin.png"), location: CGPointMake(200, 110), name: "bluePinA", axisView: axisView)

bluePinB = PinImageView(imageIcon: UIImage(named: "blue_pin.png"), location: CGPointMake(240, 110), name: "bluePinB", axisView: axisView)

view.addSubview(redPinA)
view.addSubview(redPinB)
view.addSubview(bluePinA)
view.addSubview(bluePinB)
}

}

我从您的评论中推断您尝试直接调用此代码来解决 setNeedsDisplay 没有导致 drawRect 被调用的问题。这听起来像是一个单独的问题。解决方案不是自己调用 drawRect(或 drawAxis),而是找出为什么 setNeedsDisplay 没有完成这项工作。但是问题不在于您问题中的代码,而显然是其他问题的结果。

关于ios - Swift:为什么在 touchesBegan() 中将 UIView 的帧大小引用为 (0.0, 0.0)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35389549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com