我需要一些帮助才能开始绘制两端带有圆圈的线并测量其长度。我能够划清界线,但不能让它移动,花了几个小时决定在 SO 上发帖。
所以请看下图并指导我开始。任何使用 objective-c 的示例或教程都会有所帮助。
谢谢 :)
最佳答案
这个想法看起来很有趣,所以我在 Xcode 中开始了一个新项目并创建了一个概念验证。
这个类负责绘制两个圆和一条连接它们中心的线。
class LineView: UIView {
var startPoint: CGPoint?
var endPoint: CGPoint?
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
private func setup() {
self.backgroundColor = UIColor.clearColor()
self.multipleTouchEnabled = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.updatePointsWithTouches(touches)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.updatePointsWithTouches(touches)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.clearPoints()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
self.clearPoints()
}
private func updatePointsWithTouches(touches: Set<UITouch>) {
if touches.count >= 1 {
self.startPoint = touches[advance(touches.startIndex, 0)].locationInView(self)
}
if touches.count >= 2 {
self.endPoint = touches[advance(touches.startIndex, 1)].locationInView(self)
}
self.setNeedsDisplay()
}
private func clearPoints() {
self.startPoint = nil
self.endPoint = nil
self.setNeedsDisplay()
}
// MARK: - Drawing
override func drawRect(rect: CGRect) {
// draw circle at startPoint
if let sp = self.startPoint {
self.drawTouchCircleAtPoint(sp)
}
// draw circle at endPoint
if let ep = self.endPoint {
self.drawTouchCircleAtPoint(ep)
}
// draw line between points
if let sp = self.startPoint, ep = self.endPoint {
self.drawLineBetweenFirstPoint(sp, secondPoint: ep)
}
}
private func drawTouchCircleAtPoint(p: CGPoint) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
CGContextSetLineWidth(context, 2.0)
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.6)
CGContextAddArc(context, p.x, p.y, CGFloat(30.0), CGFloat(0.0), CGFloat(M_PI * 2), 1)
CGContextFillPath(context)
CGContextRestoreGState(context)
}
private func drawLineBetweenFirstPoint(p1: CGPoint, secondPoint p2: CGPoint) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().colorWithAlphaComponent(0.6).CGColor)
CGContextSetLineWidth(context, 1.0)
CGContextMoveToPoint(context, p1.x, p1.y)
CGContextAddLineToPoint(context, p2.x, p2.y)
CGContextStrokePath(context)
CGContextRestoreGState(context)
}
}
此类引入了两个私有(private)属性:startPoint 和 endPoint,它们跟踪用户手指触摸 View 的位置。
在这个类中,您会发现一个从所有初始化程序调用的 setup() 函数。 self.multipleTouchEnabled = true 在这里至关重要,因此 View 可以同时检测到多个触摸。
touchesBegan/Moved/Ended/Cancelled 函数调用辅助函数,提取 touches 集中 UITouch 实例的位置。
最后,最后三个函数负责绘制圆和连接线。
class InteractiveImageView: UIImageView {
private var lineView: LineView!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
private func setup() {
self.userInteractionEnabled = true
self.lineView = LineView(frame: self.bounds)
self.addSubview(self.lineView)
}
}
这个 UIImageView 子类有一个嵌入的 LineView 来捕获多点触摸事件。
您也可以将这些类与 Storyboard 一起使用!只需拖出一个 UIImageView,将其类更改为 InteractiveImageView,设置适当的约束,然后运行该应用程序。我会留给您在圆心之间的轴上绘制文本。
对于寻求Objective-C解决方案的人,请参阅下面的LineView和InteractiveImageView实现文件。
#import "LineView.h"
@interface LineView ()
@property (nonatomic) CGPoint startPoint;
@property (nonatomic) CGPoint endPoint;
@end
@implementation LineView
- (instancetype)init
{
self = [super init];
if (self) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self setup];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup
{
self.backgroundColor = [UIColor clearColor];
self.multipleTouchEnabled = true;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self updatePointsWithTouches:touches];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self updatePointsWithTouches:touches];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self clearPoints];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self clearPoints];
}
- (void)clearPoints
{
self.startPoint = CGPointZero;
self.endPoint = CGPointZero;
[self setNeedsDisplay];
}
- (void)updatePointsWithTouches:(NSSet *)touches
{
if (touches.count >= 1) {
UITouch *touch = [touches allObjects][0];
self.startPoint = [touch locationInView:self];
}
if (touches.count >= 2) {
UITouch *touch = [touches allObjects][1];
self.endPoint = [touch locationInView:self];
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
if (self.startPoint.x != 0 && self.startPoint.y != 0) {
[self drawTouchCircleAtPoint:self.startPoint];
}
if (self.endPoint.x != 0 && self.endPoint.y != 0) {
[self drawTouchCircleAtPoint:self.endPoint];
}
if (self.endPoint.x != 0 && self.endPoint.y != 0 &&
self.startPoint.x != 0 && self.startPoint.y != 0) {
[self drawLineBetweenFirstPoint:self.startPoint end:self.endPoint];
}
}
- (void)drawLineBetweenFirstPoint:(CGPoint)startPoint end:(CGPoint)endPoint
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetStrokeColorWithColor(context, [[[UIColor whiteColor] colorWithAlphaComponent:0.6] CGColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
- (void)drawTouchCircleAtPoint:(CGPoint)CirclePoint
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetLineWidth(context, 2.0);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.6);
CGContextAddArc(context, CirclePoint.x, CirclePoint.y, 30.0, 30.0, M_PI * 2, YES);
CGContextFillPath(context);
CGContextRestoreGState(context);
}
@end
#import "InteractiveImageView.h"
#import "LineView.h"
@interface InteractiveImageView ()
@property (strong, nonatomic) LineView *lineView;
@end
@implementation InteractiveImageView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self setup];
}
return self;
}
- (void)setup
{
self.userInteractionEnabled = YES;
self.lineView = [[LineView alloc] initWithFrame:self.bounds];
[self addSubview:self.lineView];
}
@end
关于图片上的iOS线测量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31066519/
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上