ios - swift xcode : How do I draw on the same view as a text field plus a list of buttons?

标签 ios xcode swift

我正在尝试创建的屏幕截图: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)未删除。

This is how your bindings should look

在 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/

相关文章:

ios - 从 NSMutableArray 中删除重复的坐标

iphone - 一台特定 iOS 设备的新崩溃日志未出现在管理器中

xcode - IOS 6 Xcode 4.5 MFMailComposer 崩溃

ios - 如何覆盖 Alamofire SessionManager 以修改响应以添加 header ?

ios - 如何在 swift 中附加两个 NSData 变量?

ios - Swift - socket 无法连接到重复内容

ios - 如何将 TextView 的文本设置为通过从应用程序操作扩展接收文本创建的字符串

ios - 如何按用户或自动获取时间设置 ios

ios - Remote Simulator to Windows 选项不存在

c++ - 有没有一种使用 C++ 在 mac OS X 中打开一个(或多个)opengl 窗口的简单方法?