Код UIDynamics [__NSCFNumber center] и журнал сбоев включены
Я хочу ознакомиться с некоторыми примерами кода из онлайн-учебника, который прекрасно работает, прежде чем я добавлю в него свою функцию. Я хочу добавить UIDynamics и применить гравитацию к ряду точек на линии на графике / графике и просто заставить его упасть с экрана, но мне кажется, что-то не хватает? Это происходит сбой из-за того, что [__NSCFNumber center] нераспознанный селектор отправляется в экземпляр, если кто-нибудь может сказать мне, почему мне это понравится.
Онлайновый образец взят с сайта Рэя Вендерлиха и написан Кэролайн Бегби для обучения. Работает отлично. Единственная функция, которую я добавил, однако, разбивает это.
import UIKit
@IBDesignable class GraphView: UIView {
var graphPoints:[Int] = [4, 2, 6, 4, 5, 8, 3]
@IBInspectable var startColor: UIColor = UIColor.redColor()
@IBInspectable var endColor: UIColor = UIColor.greenColor()
override func drawRect(rect: CGRect) {
let width = rect.width
let height = rect.height
var path = UIBezierPath(roundedRect: rect,
byRoundingCorners: UIRectCorner.AllCorners,
cornerRadii: CGSize(width: 8.0, height: 8.0))
path.addClip()
let context = UIGraphicsGetCurrentContext()
let colors = [startColor.CGColor, endColor.CGColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorLocations:[CGFloat] = [0.0, 1.0]
let gradient = CGGradientCreateWithColors(colorSpace,
colors,
colorLocations)
var startPoint = CGPoint.zeroPoint
var endPoint = CGPoint(x:0, y:self.bounds.height)
CGContextDrawLinearGradient(context,
gradient,
startPoint,
endPoint,
0)
let margin:CGFloat = 20.0
var columnXPoint = { (column:Int) -> CGFloat in
/
let spacer = (width - margin*2 - 4) /
CGFloat((self.graphPoints.count - 1))
var x:CGFloat = CGFloat(column) * spacer
x += margin + 2
return x
}
let topBorder:CGFloat = 60
let bottomBorder:CGFloat = 50
let graphHeight = height - topBorder - bottomBorder
let maxValue = maxElement(graphPoints)
var columnYPoint = { (graphPoint:Int) -> CGFloat in
var y:CGFloat = CGFloat(graphPoint) /
CGFloat(maxValue) * graphHeight
y = graphHeight + topBorder - y /
return y
}
UIColor.whiteColor().setFill()
UIColor.whiteColor().setStroke()
var graphPath = UIBezierPath()
graphPath.moveToPoint(CGPoint(x:columnXPoint(0),
y:columnYPoint(graphPoints[0])))
for i in 1..<graphPoints.count {
let nextPoint = CGPoint(x:columnXPoint(i),
y:columnYPoint(graphPoints[i]))
graphPath.addLineToPoint(nextPoint)
}
CGContextSaveGState(context)
var clippingPath = graphPath.copy() as! UIBezierPath
clippingPath.addLineToPoint(CGPoint(
x: columnXPoint(graphPoints.count - 1),
y:height))
clippingPath.addLineToPoint(CGPoint(
x:columnXPoint(0),
y:height))
clippingPath.closePath()
clippingPath.addClip()
let highestYPoint = columnYPoint(maxValue)
startPoint = CGPoint(x:margin, y: highestYPoint)
endPoint = CGPoint(x:margin, y:self.bounds.height)
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
CGContextRestoreGState(context)
graphPath.lineWidth = 2.0
graphPath.stroke()
for i in 0..<graphPoints.count {
var point = CGPoint(x:columnXPoint(i), y:columnYPoint(graphPoints[i]))
point.x -= 5.0/2
point.y -= 5.0/2
let circle = UIBezierPath(ovalInRect:
CGRect(origin: point,
size: CGSize(width: 5.0, height: 5.0)))
circle.fill()
}
var linePath = UIBezierPath()
linePath.moveToPoint(CGPoint(x:margin, y: topBorder))
linePath.addLineToPoint(CGPoint(x: width - margin,
y:topBorder))
linePath.moveToPoint(CGPoint(x:margin,
y: graphHeight/2 + topBorder))
linePath.addLineToPoint(CGPoint(x:width - margin,
y:graphHeight/2 + topBorder))
linePath.moveToPoint(CGPoint(x:margin,
y:height - bottomBorder))
linePath.addLineToPoint(CGPoint(x:width - margin,
y:height - bottomBorder))
let color = UIColor(white: 1.0, alpha: 0.3)
color.setStroke()
linePath.lineWidth = 1.0
linePath.stroke()
createFallAnimation() // my only func I added to the project
}
// My new code added to the project that is crashing it.
func createFallAnimation() {
var animator:UIDynamicAnimator? = nil
animator = UIDynamicAnimator(referenceView:self )
let gravity = UIGravityBehavior(items: graphPoints)
gravity.gravityDirection = CGVectorMake(0.0, 0.5)
animator?.addBehavior(gravity)
}
}
Вот журнал сбоев:
2015-07-24 08:52:48.092 Flo[51164:11291157] -[__NSCFNumber center]: unrecognized selector sent to instance 0xb000000000000043
2015-07-24 08:52:48.097 Flo[51164:11291157] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber center]: unrecognized selector sent to instance 0xb000000000000043'
*** First throw call stack:
(
0 CoreFoundation 0x000000010d55cc65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f309bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010d5640ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010d4ba13c ___forwarding___ + 988
4 CoreFoundation 0x000000010d4b9cd8 _CF_forwarding_prep_0 + 120
5 UIKit 0x000000010e7b7f11 -[UIDynamicAnimator _registerBodyForItem:shape:] + 672
6 UIKit 0x000000010e7bc006 -[UIGravityBehavior _addItem:] + 43
7 UIKit 0x000000010e7bc6b5 -[UIGravityBehavior _associate] + 293
8 UIKit 0x000000010e7b5b97 -[UIDynamicAnimator _registerBehavior:] + 244
9 Flo 0x000000010d3318db _TFC3Flo9GraphView20createAnimationStufffS0_FT_T_ + 331
10 Flo 0x000000010d33166b _TFC3Flo9GraphView8drawRectfS0_FVSC6CGRectT_ + 6555
11 Flo 0x000000010d33177d _TToFC3Flo9GraphView8drawRectfS0_FVSC6CGRectT_ + 93
12 UIKit 0x000000010e0bd5d2 -[UIView(CALayerDelegate) drawLayer:inContext:] + 495
13 QuartzCore 0x0000000112930a2a -[CALayer drawInContext:] + 119
14 QuartzCore 0x000000011282a92b CABackingStoreUpdate_ + 2793
15 QuartzCore 0x0000000112930933 ___ZN2CA5Layer8display_Ev_block_invoke + 59
16 QuartzCore 0x00000001129307be _ZN2CA5Layer8display_Ev + 1478
17 QuartzCore 0x00000001129254d9 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 301
18 QuartzCore 0x0000000112925561 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
19 QuartzCore 0x000000011289186e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
20 QuartzCore 0x0000000112892a22 _ZN2CA11Transaction6commitEv + 462
21 UIKit 0x000000010e03b9ed -[UIApplication _reportMainSceneUpdateFinished:] + 44
22 UIKit 0x000000010e03c6b1 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2648
23 UIKit 0x000000010e03b095 -[UIApplication workspaceDidEndTransaction:] + 179
24 FrontBoardServices 0x0000000111aed5e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21
25 CoreFoundation 0x000000010d49041c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
26 CoreFoundation 0x000000010d486165 __CFRunLoopDoBlocks + 341
27 CoreFoundation 0x000000010d485f25 __CFRunLoopRun + 2389
28 CoreFoundation 0x000000010d485366 CFRunLoopRunSpecific + 470
29 UIKit 0x000000010e03ab02 -[UIApplication _run] + 413
30 UIKit 0x000000010e03d8c0 UIApplicationMain + 1282
31 Flo 0x000000010d3432f7 main + 135
32 libdyld.dylib 0x000000010fa3f145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
У меня такое чувство, что я не могу использовать элементы массива, которые являются интергерами? Я думаю, что они должны быть объектами? Любая помощь будет отличной. Если вы хотите возиться со всем проектом самостоятельно, его можно найти в Ray Wenderlich в Core Graphics и Swift, часть 2.
1 ответ
Это неверно, и неясно, что вы хотели, чтобы произошло:
var graphPoints:[Int] = [4, 2, 6, 4, 5, 8, 3]
...
let gravity = UIGravityBehavior(items: graphPoints)
Это говорит: "Пожалуйста, прикрепите гравитационное поведение к нескольким целым". Как целые реагируют на гравитацию?
Поведение может применяться только к вещам, которые соответствуют UIDynamicItem
(вещи, которые имеют bounds
, center
, а также transform
). Целые числа не имеют ни одного из них, и неясно, как они вообще могли.
То, что вы пытаетесь сделать (анимировать график), немного сложнее. Когда вы перемещаете точки, вам нужно будет перерисовать путь на основе новых точек. Чтобы оживить это, вам нужно использовать что-то, что может оживить пути (вероятно, CAShapeLayer
который делает это хорошо). Это будет совершенно другой код, чем в этом примере.