我正在尝试创建的屏幕截图:enter image description here
注意:如果您决定运行该项目,则无需查看下面的代码,因为我在下面发布的所有类都在 dropbox 压缩项目文件中。
底部的每个方 block 选择不同的颜色,并且在绿色方 block 的右侧有一个不可见的方 block 选择形状类型。在用户选择其中一种形状后,用户将能够在屏幕的特定部分进行绘图。
整个项目:https://www.dropbox.com/s/h3uottk2erjcryo/SwiftXcodeProject888.zip?dl=0
如果您运行该项目,创建一个帐户,然后单击登录,然后单击其中一行,应用程序将崩溃并收到以下错误消息:
2016-03-11 15:07:04.530 finalProject2[11025:1028122] <UIView: 0x7f86334592a0; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x7f8633495310>; layer = <CALayer: 0x7f863345a550>>'s window is not equal to <finalProject2.RowTableViewController: 0x7f86336b3a20>'s view's window!
File slot 1
File slot 2
File slot 3
File slot 4
File slot 5
File slot 6
File slot 7
File slot 8
File slot 9
File slot 10
File slot 11
File slot 12
2016-03-11 15:07:06.723 finalProject2[11025:1028122] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<finalProject2.MainProjectScene 0x7f86334ae2a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key buttonForShape.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010835ce65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010a46adeb objc_exception_throw + 48
2 CoreFoundation 0x000000010835caa9 -[NSException raise] + 9
3 Foundation 0x000000010894d9bb -[NSObject(NSKeyValueCoding) setValue:forKey:] + 288
4 UIKit 0x00000001090d6320 -[UIViewController setValue:forKey:] + 88
5 UIKit 0x0000000109304f41 -[UIRuntimeOutletConnection connect] + 109
6 CoreFoundation 0x000000010829d4a0 -[NSArray makeObjectsPerformSelector:] + 224
7 UIKit 0x0000000109303924 -[UINib instantiateWithOwner:options:] + 1864
8 UIKit 0x00000001090dceea -[UIViewController _loadViewFromNibNamed:bundle:] + 381
9 UIKit 0x00000001090dd816 -[UIViewController loadView] + 178
10 UIKit 0x00000001090ddb74 -[UIViewController loadViewIfRequired] + 138
11 UIKit 0x00000001090de2e7 -[UIViewController view] + 27
12 UIKit 0x0000000109888f87 -[_UIFullscreenPresentationController _setPresentedViewController:] + 87
13 UIKit 0x00000001090adf62 -[UIPresentationController initWithPresentedViewController:presentingViewController:] + 133
14 UIKit 0x00000001090f0c8c -[UIViewController _presentViewController:withAnimationController:completion:] + 4002
15 UIKit 0x00000001090f3f2c -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 489
16 UIKit 0x00000001090f3a3b -[UIViewController presentViewController:animated:completion:] + 179
17 UIKit 0x00000001090f90df -[UIViewController _showViewController:withAction:sender:] + 280
18 UIKit 0x0000000109547874 __66-[UIStoryboardShowSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 147
19 UIKit 0x0000000109670f5c -[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 460
20 UIKit 0x0000000109670d5f -[UIStoryboardSegueTemplate _perform:] + 82
21 UIKit 0x0000000109671023 -[UIStoryboardSegueTemplate perform:] + 156
22 UIKit 0x000000010908acee -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1775
23 UIKit 0x000000010908afb3 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 388
24 UIKit 0x0000000108f534a2 _runAfterCACommitDeferredBlocks + 317
25 UIKit 0x0000000108f66c01 _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
26 UIKit 0x0000000108f72af3 _afterCACommitHandler + 90
27 CoreFoundation 0x0000000108288367 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
28 CoreFoundation 0x00000001082882d7 __CFRunLoopDoObservers + 391
29 CoreFoundation 0x000000010827df2b __CFRunLoopRun + 1147
30 CoreFoundation 0x000000010827d828 CFRunLoopRunSpecific + 488
31 GraphicsServices 0x000000010e332ad2 GSEventRunModal + 161
32 UIKit 0x0000000108f47610 UIApplicationMain + 171
33 finalProject2 0x000000010815017d main + 109
34 libdyld.dylib 0x000000010af7392d start + 1
35 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
MainProject 场景类:
import UIKit
weak var FirstFileNameTextField: UILabel!
enum ShapeType: String
{
case Line = "Line"
case Ellipse = "Ellipse"
case Rectangle = "Rectangle"
case FilledEllipse = "Filled Ellipse"
case FilledRectangle = "Filled Rectangle"
case Scribble = "Scribble"
}
let shapes: [ShapeType] = [ .Line, .Ellipse, .Rectangle, .FilledEllipse, .FilledRectangle, .Scribble ]
class MainProjectScene: UIViewController
{
var row: Row?
@IBAction func PressedSaveAs(sender: UIButton) //this is the save as function that I would like to know how to change
{
//1. Create the alert controller.
var alert = UIAlertController(title: "Name/rename your file:", message: "Enter a filename to name/rename and save your file", preferredStyle: .Alert)
//2. Add the text field. You can configure it however you need.
alert.addTextFieldWithConfigurationHandler({ (textField) -> Void in
textField.text = "Your file name"
})
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:
{
(action) -> Void in
let textField = alert.textFields![0] as UITextField
print("Text field: \(textField.text)")
// rows.cell.textLabel?.text = textField.text
CurrentFileName = textField.text!
rows[IndexPath.row].FileName = textField.text!
rows[IndexPath.row].UserText = self.TextUserScrollEdit.text!
}))
// 4. Present the alert.
self.presentViewController(alert, animated: true, completion: nil)
// rows[indexPath.row].FileName = rows.cell.textLabel?.text
// rows[i] = textField.text
// if let detailViewController = segue.destinationViewController as? MainProjectScene {
// if let cell = sender as? UITableViewCell {
// if let indexPath = self.tableView.indexPathForCell(cell) {
// detailViewController.row = rows[indexPath.row]
}
override func viewWillAppear(animated: Bool)
{
if let r = row
{
row!.FileName = r.FileName
row!.QuartzImage = r.QuartzImage
row!.UserText = r.UserText
rows[IndexPath.row].UserText = self.TextUserScrollEdit.text! }
}
override func viewDidLoad()
{
super.viewDidLoad()
TextUserScrollEdit.text = rows[IndexPath.row].UserText
// FacebookButton.addTarget(self, action: "didTapFacebook", forControlEvents: .TouchUpInside)
}
@IBOutlet weak var TextUserScrollEdit: UITextView!
@IBOutlet weak var NewFileButton: UIButton!
@IBOutlet weak var TwoDQuartzButton: UIButton!
@IBOutlet weak var YouTubeButton: UIButton!
@IBOutlet weak var TwitterButton: UIButton!
@IBOutlet weak var OpenFileButton: UIButton!
@IBOutlet weak var SnapChatButton: UIButton!
@IBOutlet weak var FacebookButton: UIButton!
@IBAction func PressedTwoDQuartzButton(sender: UIButton) {
}
@IBAction func PressedSnapchatButton(sender: UIButton){
UIApplication.sharedApplication().openURL(NSURL(string: "https://www.snapchat.com/")!)
}
@IBAction func PressedYouTubeButton(sender: UIButton) {
UIApplication.sharedApplication().openURL(NSURL(string: "https://www.youtube.com/")!)
}
@IBOutlet weak var InstagramButton: UIButton!
@IBAction func PressedFacebookButton(sender: UIButton) {
UIApplication.sharedApplication().openURL(NSURL(string: "http://www.facebook.com")!)
}
@IBAction func PressedInstagramButton(sender: UIButton) {
UIApplication.sharedApplication().openURL(NSURL(string: "https://www.instagram.com/")!)
}
@IBAction func PressedTwitterButton(sender: UIButton) {
UIApplication.sharedApplication().openURL(NSURL(string: "https://twitter.com/")!)
}
@IBOutlet weak var SaveAsButton: UIButton!
// @IBOutlet weak var shapeButton: ShapeButton!
@IBOutlet weak var canvas: CanvasView!
@IBOutlet var colorButtons: [UIButton]!
@IBOutlet weak var shapeButton: ShapeButton!
@IBAction func selectColor(sender: UIButton) {
UIView.animateWithDuration(0.5, delay: 0.0,
usingSpringWithDamping: CGFloat(0.25),
initialSpringVelocity: CGFloat(0.25),
options: UIViewAnimationOptions.CurveEaseInOut, animations: {
for button in self.colorButtons {
button.frame.origin.y = self.view.bounds.height - 58
}
sender.frame.origin.y -= 20
}, completion: nil)
canvas.color = sender.backgroundColor!
shapeButton.color = sender.backgroundColor!
}
@IBAction func selectShape(sender: ShapeButton) {
let title = "Select Shape"
let alertController = UIAlertController(title: title, message: nil, preferredStyle: .ActionSheet)
for shape in shapes {
let action = UIAlertAction(title: shape.rawValue, style: .Default) { action in
sender.shape = shape
self.canvas.shape = shape
}
alertController.addAction(action)
}
presentViewController(alertController, animated: true, completion: nil)
}
}
形状按钮类:
import UIKit
class ShapeButton: UIButton {
let shapes: [ShapeType] = [ .Line, .Ellipse, .Rectangle, .FilledEllipse, .FilledRectangle, .Scribble ]
var shape: ShapeType = .Line {
didSet {
setNeedsDisplay()
}
}
var color: UIColor = UIColor.blueColor() {
didSet {
setNeedsDisplay()
}
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
let context = UIGraphicsGetCurrentContext()
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextSetLineWidth(context, 2)
let x1: CGFloat = 5
let y1: CGFloat = 5
let x2: CGFloat = frame.width - 5
let y2: CGFloat = frame.height - 5
let rect = CGRect(x: x1, y: y1 + 5, width: frame.width - 10, height: frame.height - 20)
switch shape {
case .Line:
CGContextMoveToPoint(context, x1, y1)
CGContextAddLineToPoint(context, x2, y2)
CGContextStrokePath(context)
case .Ellipse:
CGContextStrokeEllipseInRect(context, rect)
case .Rectangle:
CGContextStrokeRect(context, rect)
case .FilledEllipse:
CGContextFillEllipseInRect(context, rect)
case .FilledRectangle:
CGContextFillRect(context, rect)
case .Scribble:
CGContextMoveToPoint(context, x1, y1)
CGContextAddCurveToPoint(context,
x1 + 80, y1 - 10, // the 1st control point
x2 - 80, y2 + 10, // the 2nd control point
x2, y2) // the end point
CGContextStrokePath(context)
}
}
}
Canvas View 类:
import UIKit
/*
This program is for Xcode 6.3 and Swift 1.2
*/
class CanvasView: UIView {
var shape: ShapeType = .Line
var color: UIColor = UIColor.blueColor()
var first :CGPoint = CGPointZero
var last :CGPoint = CGPointZero
var points: [CGPoint] = []
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
let context = UIGraphicsGetCurrentContext()
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextSetFillColorWithColor(context, color.CGColor)
let rect = CGRect(x: first.x, y: first.y, width: last.x - first.x, height: last.y - first.y)
switch shape {
case .Line:
CGContextMoveToPoint(context, first.x, first.y)
CGContextAddLineToPoint(context, last.x, last.y)
CGContextStrokePath(context)
case .Ellipse:
CGContextStrokeEllipseInRect(context, rect)
case .Rectangle:
CGContextStrokeRect(context, rect)
case .FilledEllipse:
CGContextFillEllipseInRect(context, rect)
case .FilledRectangle:
CGContextFillRect(context, rect)
case .Scribble:
CGContextMoveToPoint(context, first.x, first.y)
for p in points {
CGContextAddLineToPoint(context, p.x, p.y)
}
CGContextStrokePath(context)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
first = touch.locationInView(self)
last = first
points.removeAll(keepCapacity: true)
if shape == .Scribble {
points.append(first)
}
setNeedsDisplay()
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
last = touch.locationInView(self)
if shape == .Scribble {
points.append(last)
}
setNeedsDisplay()
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
last = touch.locationInView(self)
if shape == .Scribble {
points.append(last)
}
setNeedsDisplay()
}
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
}
}
最佳答案
在您的 Storyboard中,您有两个用于清除按钮的绑定(bind)。看起来您有一个名为 buttonForShape 的绑定(bind),然后决定重命名它或其他名称。 Storyboard中的绑定(bind)未删除。
在 Storyboard上,转到绑定(bind)面板并单击 x 以删除额外的绑定(bind)。
关于ios - swift xcode : How do I draw on the same view as a text field plus a list of buttons?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35950203/