Code Monkey home page Code Monkey logo

maliang's Introduction

Banner

CI Status Platform Version Carthage compatible Language codebeat badge License twitter weibo

icon MaLiang is a painting framework based on Metal. It supports drawing and handwriting with customized textures. The name of "MaLiang" comes from a boy who had a magical brush in Chinese ancient fairy story.

Simplified Chinese

☕️ If I have saved your time, buy me a cup of coffee

📱 App based on MaLiang is now avaliable on the App Store

Features

  • Lines with Bezier Curve
  • Texture Rotation
  • Glowing Lines
  • Chartlet element (for image and any other content from an UIView snapshot)
  • Force based Adjustment for stroke size
  •  Pencil supported
  • 3D Touch supported
  • Undo & Redo
  • Zoom & Scale
  • Export to image
  • Save vector contents to disk
  • support macOS Catalyst

Requirements

iOS 9.0, Swift 5

The core painting module is based on Metal

You can simply make it compatible with lower version of iOS and swift by changing only serval lines of code.

Installation

CocoaPods

MaLiang is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'MaLiang'

To use the old OpenGL ES verion:

pod 'MaLiang', '~> 1.1'

Carthage

To integrate MaLiang into your Xcode project using Carthage, specify it in your Cartfile:

github "Harley-xk/MaLiang"

Run carthage update to build the framework and drag the built MaLiang.framework into your Xcode project.

Make sure to add MaLiang.framework to your target's Embedded Binaries

Usage

MaLiang is simple to use.

  1. import MaLiang
  2. enjoy painting!

Canvas

open class Canvas: MetalView

A Canvas is the basic component of MaLiang. You will paint all things on it. Canvas extends from MetalView, whitch extends from MTKView. MetalView handles all the logic with MetalKit and hides them from you.

Canvas can be simply created with xib or code.

  • with xib or storyboard, simply drag and drop an UIView object into your view controller and change it's class to Canvas and module to MaLiang
  • with code, just create with init(frame:) as any UIView you do before.

Now, all things necessary is done!

Snapshot

You can take snapshot on canvas now. Just call snapshot function on Canvas and you will get an optional UIImage object.

Brush

With all things done, you can do more with Brush!

Brush is the key feature to MaLiang. It holds textures and colors, whitch makes it possiable to paint amazing things.

Register a Brush with image data or file to Canvas and paint with it:

let path = Bundle.main.path(forResource: "pencil", ofType: "png")!
let pencil = try? canvas.registerBrush(with: URL(fileURLWithPath: path))
pencil?.use()

Brush have serval properties for you to custmize:

// opacity of texture, affects the darkness of stroke
// set opacity to 1 may cause heavy aliasing
open var opacity: CGFloat = 0.3

// width of stroke line in points
open var pointSize: CGFloat = 4

// this property defines the minimum distance (measureed in points) of nearest two textures
// defaults to 1, this means erery texture calculated will be rendered, dictance calculation will be skiped
open var pointStep: CGFloat = 1

// sensitive of pointsize changed from force, from 0 - 1
open var forceSensitive: CGFloat = 0

/// color of stroke
open var color: UIColor = .black

// indicate if the stroke size in visual will be scaled along with the Canvas
// defaults to false, the stroke size in visual will stay with the original value
open var scaleWithCanvas = false

With all these properties, you can create you own brush as your imagination.

Force & 3D Touch

MaLiang supports automatically adjustment of stroke size with painting force. 3D Touch is supported by default, and simulated force will be setup on devices those are not supporting this.

forceSensitive is the property that force affects the storke size. It should be set between 0 to 1. the smaller the value is, the less sensitive will be. if sets to 0, then force will not affects the stroke size.

Chartlet

Chartlet elements are supported from 2.1.0. A chartlet must be registered to canvas with its' texture data. You can simply get image data from its' pngData() method.

let data = UIImage(named: "chartlet").pngData()
let texture = try canvas.makeTexture(with: data)

You can apply rotation to chartlet by passing a counter clockwise angle in radius when adding it to the canvas:

canvas.renderChartlet(at: location, size: chartletSize, textureID: texture.id, rotation: angle)

Text

Text element can be rendered to canvas by the Chartlet feature. MaLiang leaves the work of text layout and styles to your self.

  • Firtst, put your text content to a label, a text view or any other customized views
  • Second, make it properly styled and layouted
  • Then Third, take a snapshot from that view.
  • Finally, now you shoud have an image to your text content, render this image to canvas using the Chartlet apis.

Refer to the samples for more details.

CanvasData

CanvasData is now configured by default. It holds all the data on the Canvas, and makes the undo and redo actions to be possiable.
And you can implement your own saving logic with the data holds by CanvasData.

Saving

🎉 You can save your paintings to disk now.

// 1. create an instance of `DataExporter` with your canvas:
let exporter = DataExporter(canvas: canvas)
// 2. save to empty folders on disk:
exporter.save(to: localPath, progress: progressHandler, result: resultHandler)

// also you can use another synchronous method to do this work Synchronously
exporter.saveSynchronously(to: locakPath, progress: progressHandler)

Then, contents of canvas and some document infomations will be saved to files in the directory you provided.

MaLiang does not zip the folders, you can implement your own archive Logics refer to the sample project

Reading

Use DataImporter to read data saved by MaLiang to your canvas:

DataImporter.importData(from: localPath, to: canvas, progress: progressHandler, result: resultHandler)

Also, the localPath passed into DataImporter must be a folder where your contents files place. If you are using your own archive logic, unzip the contents first by your own.

License

MaLiang is available under the MIT license. See the LICENSE file for more info.

maliang's People

Contributors

harley-xk avatar honghaoz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maliang's Issues

X and Y start point coordinate issue on ipad and phone

Hi MaLiang,

This is very helpful.But when I'm trying to draw lines with pen, but not connected two line. It only recognizes every second stroke and does not start writing at exact point of contact. When I'm zooming then it's more skip point instead of start point.

Please help me ASAP. Please review attached screenshot for understand issues.
simulator screen shot - ipad pro 12 9-inch 2nd generation - 2019-01-22 at 18 54 32

Thank You MaLiang.

Straight lines

How do you achieve perfect straight lines? Any tips or suggestions would be helpful.

Thank You!

Not compiled in latest version(1.1.8) of MaLiang

Hi, dear.

I tried to build the Example in MaLiang downloads with pod install with cocoa pods.
Here is the Podfile where I did new line, pod 'MaLiang' for Maliang.

use_frameworks!

target 'MaLiang_Example' do

pod 'Comet'
pod 'MaLiang'

end

But, many erros arise when build.
For example,

MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIAlertController+Comet.swift:13:64: 'Style' is not a member type of 'UIAlertAction'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIBarButtonItem+Closure.swift:17:69: 'Style' is not a member type of 'UIBarButtonItem'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:92:91: Type 'UIResponder' has no member 'keyboardWillShowNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:94:90: Type 'UIResponder' has no member 'keyboardDidShowNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:95:98: Type 'UIResponder' has no member 'keyboardWillChangeFrameNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:149:42: Type 'UIResponder' has no member 'keyboardAnimationDurationUserInfoKey'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIVIew+Comet.swift:65:98: 'OptionsKey' is not a member type of 'UINib'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:150:26: Type 'UIView' has no member 'AnimationOptions'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:167:34: Type 'UIResponder' has no member 'keyboardFrameEndUserInfoKey'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:180:22: Type 'UIView' has no member 'AnimationOptions'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UINavigationBar+Comet.swift:27:59: Type 'NSAttributedString' has no member 'Key'

...

MaLiang-fgkbrzhxgpualzdixhtqfoxfrjaj/Build/Products/Debug-iphoneos/Comet/Comet.framework/Modules/module.modulemap:9:12: Header 'Comet-Swift.h' not found
MaLiang-1.1.8/Example/MaLiang/ViewController.swift:10:8: Could not build Objective-C module 'Comet'
Command Ditto failed with a nonzero exit code

Would you help me, please ?
Thanks.

Eraser is not round

When I change to eraser mode ,the brush is not round ,
but the texture image 'point.png' is round,
then I change eraser color to red
can see the red round with white border

Missing 'registerBrush' method on canvas

I followed your steps, however when I try to register a brush it gives me an error.
Thank you for your time. Also, it works fine on your example project. But I want to use it on mine so I am having difficulties.

老哥,TODO中的内容实现了嘛

正好需要这方面的资料参考,刚好看到这个项目 非常棒👍

请问,这俩功能有计划更新吗?

  • 绘制文本到画布中的指定位置
  • 绘制指定的图片到画布中的指定位置

Crash

Thank you for such an awesome library! Its helping me. However, a crash occurred multiple times in my console .

at let textureLoader = MTKTextureLoader(device: device!)

library version - 2.6.1
with ios version: 10.3.3 and 9.3.5

log.pdf

Missing `registerChartlet` method on Canvas

First off thanks for sharing this great framework!
It looks like the 'registerChartlet' method is missing on the Canvas class. So we're getting an error in the TextureElementSamples view controller.

Last update broke some brushes

It looks like the one of the recent updates broke the pencil, brush and claw brushes. There's no output on those strokes.

请教一个问题

我想把UIBezierPath的线转换成Metal绘制出来,该用什么思路去实现呢?
例如我从paintCode得到一段绘制代码:

    //绘制swift logo
    var bezierPath = UIBezierPath()
    bezierPath.moveToPoint(CGPointMake(96.14, 86.59))
    bezierPath.addCurveToPoint(CGPointMake(56.82, 94.83), controlPoint1: CGPointMake(81.83, 85.02), controlPoint2: CGPointMake(87.1, 95.75))
    bezierPath.addCurveToPoint(CGPointMake(20.01, 79.31), controlPoint1: CGPointMake(42.17, 94.39), controlPoint2: CGPointMake(29.06, 87.05))
    bezierPath.addCurveToPoint(CGPointMake(5.25, 62.38), controlPoint1: CGPointMake(10.35, 71.06), controlPoint2: CGPointMake(5.25, 62.38))
    bezierPath.addCurveToPoint(CGPointMake(35.2, 74.85), controlPoint1: CGPointMake(5.25, 62.38), controlPoint2: CGPointMake(17.28, 72.33))
    bezierPath.addCurveToPoint(CGPointMake(64.02, 69.54), controlPoint1: CGPointMake(53.11, 77.37), controlPoint2: CGPointMake(64.02, 69.54))
    bezierPath.addCurveToPoint(CGPointMake(37.43, 44.73), controlPoint1: CGPointMake(64.02, 69.54), controlPoint2: CGPointMake(49.91, 58.13))
    bezierPath.addCurveToPoint(CGPointMake(14.97, 16.34), controlPoint1: CGPointMake(24.96, 31.34), controlPoint2: CGPointMake(14.97, 16.34))
    bezierPath.addCurveToPoint(CGPointMake(40.56, 37.05), controlPoint1: CGPointMake(14.97, 16.34), controlPoint2: CGPointMake(31.85, 30.51))
    bezierPath.addCurveToPoint(CGPointMake(56.82, 47.75), controlPoint1: CGPointMake(45.62, 40.86), controlPoint2: CGPointMake(56.82, 47.75))
    bezierPath.addCurveToPoint(CGPointMake(43.08, 32.22), controlPoint1: CGPointMake(56.82, 47.75), controlPoint2: CGPointMake(47.12, 37.33))
    bezierPath.addCurveToPoint(CGPointMake(27.99, 11.26), controlPoint1: CGPointMake(37.51, 25.17), controlPoint2: CGPointMake(27.99, 11.26))
    bezierPath.addCurveToPoint(CGPointMake(55.05, 35.46), controlPoint1: CGPointMake(27.99, 11.26), controlPoint2: CGPointMake(45.04, 27.34))
    bezierPath.addCurveToPoint(CGPointMake(78.26, 52.03), controlPoint1: CGPointMake(61.79, 40.93), controlPoint2: CGPointMake(78.26, 52.03))
    bezierPath.addCurveToPoint(CGPointMake(80.71, 31.34), controlPoint1: CGPointMake(78.26, 52.03), controlPoint2: CGPointMake(81.63, 45.61))
    bezierPath.addCurveToPoint(CGPointMake(69.08, 3), controlPoint1: CGPointMake(79.8, 17.06), controlPoint2: CGPointMake(69.08, 3))
    bezierPath.addCurveToPoint(CGPointMake(97.29, 34.58), controlPoint1: CGPointMake(69.08, 3), controlPoint2: CGPointMake(89.12, 14.76))
    bezierPath.addCurveToPoint(CGPointMake(100.25, 67.8), controlPoint1: CGPointMake(105.45, 54.4), controlPoint2: CGPointMake(100.25, 67.8))
    bezierPath.addCurveToPoint(CGPointMake(107.29, 81.07), controlPoint1: CGPointMake(100.25, 67.8), controlPoint2: CGPointMake(104.47, 72.3))
    bezierPath.addCurveToPoint(CGPointMake(107.96, 96.25), controlPoint1: CGPointMake(110.12, 89.84), controlPoint2: CGPointMake(107.96, 96.25))
    bezierPath.addCurveToPoint(CGPointMake(96.14, 86.59), controlPoint1: CGPointMake(107.96, 96.25), controlPoint2: CGPointMake(105.27, 87.59))
    bezierPath.closePath()

我想把这个图形,使用MaLiang的库绘制出来,还请大神指点一下。

iPhone X 画板放大缩小 之前的路径会消失

您好,在iPhone X上发现一个很奇怪的bug:

  1. 正常情况下画一条线
    2.放大画板再画一条线
    3.缩小画板,画线,此时之前的两条线都没有了的

发现问题卡在第三步,如果直接缩放的比例非常小,由于设置了最小缩放???,所以手松开会回弹一下到稍微大一点的比例,然后再进行绘制,就会丢失之前的数据,如果是正常慢慢缩小没问题的。

您觉得是什么原因导致的呢?

有个glBlendFunc 问题请教下

glBlendFunc(GL_ONE.gluint, GL_ONE_MINUS_SRC_ALPHA.gluint)
image

glBlendFunc(GL_ONE.gluint, GL_ZERO.gluint)
image

为什么差别这么大 ?目标颜色是多少? 对于这个混合glBlendFunc(GL_ONE.gluint, GL_ONE_MINUS_SRC_ALPHA.gluint) 我不太理解? 请教下

是否可以写一个Metal版本的呢?

OpenGL ES 在ios 12上已经被标记为废弃了的。

https://developer.apple.com/ios/whats-new/

Deprecation of OpenGL ES
Apps built using OpenGL ES will continue to run in iOS 12, but OpenGL ES is deprecated in iOS 12. Games and graphics-intensive apps that previously used OpenGL ES should now adopt Metal.

Metal is designed from the ground up to provide the best access to the modern GPUs on iOS, macOS, and tvOS devices. Metal avoids the overhead inherent in legacy technologies and exposes the latest graphics processing functionality. Unified support for graphics and compute in Metal lets your apps efficiently utilize the latest rendering techniques. For information about developing apps and games using Metal, see the developer documentation for Metal, Metal Performance Shaders, and MetalKit.

Brush Rotation

Hi @Harley-xk

I am using your library into my project its awesome but I need one thing more that is missing in this library . just like texture rotation can we build brush painting rotation and selection from one place to other .

you can see selection tool in this library.

https://github.com/Asana/Drawsana

Thanks in advance.

NSData support

Is there a way to import and export canvas data directly to NSData. Right now the import and export type is to a file in the documents directory. This support is to allow saving the canvas to database persistence stores like core data or realm.

This is my initial attempt:

  public static func contentData(from canvas: Canvas) -> NSData? {
        do {
            let encoder = JSONEncoder()
            
            let data = canvas.data
            let content = CanvasContent(lineStrips: data?.elements.compactMap { $0 as? LineStrip } ?? [],
                                        chartlets: data?.elements.compactMap { $0 as? Chartlet } ?? [])
            
            let contentData = try encoder.encode(content)
            
            return contentData as NSData
        } catch {
            print(error.localizedDescription)
            
            return nil
        }
    }
   public static func importData(value: NSData, to canvas: Canvas) {
        if value.length > 0 {
            let decoder = JSONDecoder()
            
            DispatchQueue(label: "com.maliang.importing").async {
                do {
                    let content = try decoder.decode(CanvasContent.self, from: value as Data)
                    
                    /// import elements to canvas
                    content.lineStrips.forEach { $0.brush = canvas.findBrushBy(name: $0.brushName) }
                    content.chartlets.forEach { $0.canvas = canvas }
                    canvas.data.elements = (content.lineStrips + content.chartlets).sorted(by: { $0.index < $1.index})
                    
                    DispatchQueue.main.async {
                        /// redraw must be call on main thread
                        canvas.redraw()
                    }
                } catch {
                    DispatchQueue.main.async {
                        print(error.localizedDescription)
                    }
                }
            }
        }
    }

though not completely successful as the canvas isn't loading properly from the saved data.

about glow

how about if I want draw some glow style lines,i need to change pipelineState? or renderPassDescriptor

代码创建 Canvas,画画没反应

通过 storyboard 直接拉 view 创建的话,画画就有反应。

创建 view 的代码如下:

let vvv = Canvas(frame: .zero)
vvv.frame = UIScreen.main.bounds
view.addSubview(vvv)

Cannot use Canvas(frame: CGRect)

Hi,
I have problem using the classes defined in MaLiang.
I have installed the pods and imported MaLiang inside the project.
Then I have make sure that the Maliang folder is in my project's Pod folder. This much is working.
But for some unknown reason, the Canvas class cannot be detected properly. It doesn't show the Canvas(frame:CGRect). Also the Brush is different and Bundle has conflict, not with my code but with some core codes from Xcode. I have tried Clean and re-build, also reinstall pods. All doesn't work

Do you know whats wrong?

Header MaLiang-Swift.h Not found

I got some strange error just after updating to ver 1.1.3 using 'pod update MaLiang' command
It says that header MaLiang-Swift.h is not found. I checked it and it wasn't there.
See the attached screen shot

screen shot 2018-05-25 at 1 22 49 pm

deinit of Canvas

Hi,
I think the current context must be set to nil in deinit

deinit {
   :
   if EAGLContext.current() === context {
        // EAGLContext.setCurrent(context)
        EAGLContext.setCurrent(nil)
    }
}

'Eraser' can't be found ???

发现一个问题:Cocoapods引入后,Eraser 使用时会报这个error。手动引入工程的话没有问题。

bca67bef-2552-497a-93bc-25f68aac9321

你提供的example换成pod 引入也存在这个问题:

300f0f51-5bd8-48ba-9149-a03504d3f821

Normalized opacity?

This is more of a request than an issue, but is there a technique for locking the max opacity of a stroke to a given value?
For example, say I set the brush opacity to 0.25 and the pointStep to 1. The individual samples render with an opacity of 0.25 but as they overlap it quickly goes up to 1.0.
Do you have any ideas of how I can reliably keep the max opacity at a given value?

初始化的时候闪退"error 'vertexFunction must not be nil.'"

请问一下,为什么初始化调用的时候一直闪退呢?
logo:

[4690:2837285] Metal GPU Frame Capture Enabled
[4690:2837285] Metal API Validation Enabled
[4690:2837285] -[MTLRenderPipelineDescriptorInternal validateWithDevice:], line 2395: error 'vertexFunction must not be nil.'
-[MTLRenderPipelineDescriptorInternal validateWithDevice:]:2395: failed assertion `vertexFunction must not be nil.'

image

断点调试发现是找不到这个文件导致的,不知道怎么解决
image

调用:

    lazy var canvas: Canvas = {
        let canvas = Canvas.init(frame: CGRect.init(x: 0, y: 0, width: 500, height: 500))
        return canvas
    }()

Modifying to detect a line

Hi,
In my app, I want the painting to be able to detect if it reaches the edge. Its painting on PNG format with black line alpha 0.5-1, the rest are transparent.
I found that your code handles all the painting in the MaLiang podfile.

Thus, which class and method should I override so when we detect the edges, it will stop coloring. Then it will begin coloring again when getting back in. This happens even user have not lift up his/her fingers.
Or do you have a method that I can call to enable/disable painting?
Any suggestions?

smooth brush strokes

the brush strokes are not smooth, when the pointStep is 1 or less. How do you make the strokes smooth on the edges of the lines?

丢笔

我在学习ios 的opengl技术,我想请教下,为什么我在比较快的情况下画笔会出现丢笔的情况

The brush color is always black

Reproduce steps:

  1. Launch example
  2. Back to main view(exit Single View)
  3. Enter Single View again
  4. change any color, draw on canvas

writing W's

for some reason when you write W's on canvas it doesn't render properly compared to alternative drawing programs. This is in particular when you try to write small W's. Only the last stroke for the w is registered giving it a V shape instead of a W.

For example, this is how it appears in the demo app:
IMG_2156

and this is how w's show up in paper:
IMG_2157

Do you know what the issue is and how it might be resolved?

求思路

用这个库,实现在图片上涂鸦的功能,应该怎么做

Crashed: com.apple.main-thread EXC_BREAKPOINT 0x0000000100a01264

频繁操作的情况下,撤销功能crash了的。 日志如下:


#0. Crashed: com.apple.main-thread
0  Fun Draw                       0x100a01264 _T08Fun_Draw6MLViewC7textureSQyAA9MLTextureCGvWTf4dn_n (MLView.swift:65)
1  Fun Draw                       0x1009dfbdc Canvas.redraw() -> () (Canvas.swift:115)
2  Fun Draw                       0x100a08e14 specialized SketchpadViewController.actionForUndo(UIButton) -> () + 4378856980
3  Fun Draw                       0x100a0491c @objc SketchpadViewController.actionForUndo(UIButton) -> () + 4378839324
4  UIKitCore                      0x1b1957ec0 -[UIApplication sendAction:to:from:forEvent:] + 96
5  UIKitCore                      0x1b1a7ccdc -[UIControl sendAction:to:forEvent:] + 80
6  UIKitCore                      0x1b1a7cffc -[UIControl _sendActionsForEvents:withEvent:] + 440
7  UIKitCore                      0x1b1a7bffc -[UIControl touchesEnded:withEvent:] + 568
8  UIKitCore                      0x1b20f43e0 -[UIWindow _sendTouchesForEvent:] + 2472
9  UIKitCore                      0x1b20f5644 -[UIWindow sendEvent:] + 3156
10 UIKitCore                      0x1b1971fa4 -[UIApplication sendEvent:] + 340
11 UIKitCore                      0x1b18adb34 __dispatchPreprocessedEventFromEventQueue + 1440
12 UIKitCore                      0x1b18b05a0 __handleEventQueueInternal + 4740
13 UIKitCore                      0x1b18a9134 __handleHIDEventFetcherDrain + 152
14 CoreFoundation                 0x1853365b8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
15 CoreFoundation                 0x185336538 __CFRunLoopDoSource0 + 88
16 CoreFoundation                 0x185335e1c __CFRunLoopDoSources0 + 176
17 CoreFoundation                 0x185330ce8 __CFRunLoopRun + 1040
18 CoreFoundation                 0x1853305b8 CFRunLoopRunSpecific + 436
19 GraphicsServices               0x1875a1584 GSEventRunModal + 100
20 UIKitCore                      0x1b19567ac UIApplicationMain + 212
21 Fun Draw                       0x1009b5e6c main (AppDelegate.swift:14)
22 libdyld.dylib                  0x184df0c0c start + 4

iPhone7 Plus遇到操作位置和显示位置不一致的情况

试用了一下,确实优秀,但是在操作中有个点,个人觉得是存在bug 的。
随便打开一种画图模式,比如我选择的是第二个cell ,为了复现
1、我在页面画了三个圈(第一张图)
2、尽量在圈的中心方向 画一条线,都画了两遍
3、从屏幕从上到下不同位置三个圈画线来看,越往下,位置越偏移
4、第二张图是我在备忘录的画图模式按照同样的步骤操作的,能达到预期效果
ps:iPhone7 Plus,iOS12.2,希望越来越好

IMG_C4A69A53881D-1
IMG_B2172AE02F7D-1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.