假设我有以下 View 层次结构;
那些 View 实际上是 ShinobiCharts,它们是 UIView 的子类。 View1 充当用户可以触摸(捏合、平移、长按等)的主图表。该 View 反过来控制其他 View (View2、View3 等)关于特定的、触摸相关的属性(用户平移 View1,因此 View 2 和 3... 必须相应地进行操作并平移)。 但是,一旦用户滚动 UIScrollView,View1 可能会从屏幕上消失,只留下 View 2、3 等可见,它们没有相应的手势识别器,因此用户无法再与图表进行交互,糟糕用户体验。 我当然也可以将识别器添加到这些额外的图表中,但是在捏合期间,这意味着两个手指都必须位于一个 View 中,用户不能再次触摸他想要的地方以进行捏合和缩放, 糟糕的用户体验。
简而言之,我需要某种覆盖 UIScrollView 整个内容区域的触摸拦截器,这样当用户捏合或平移时,相应的触摸将被转发到主图表 (View1),而主图表又可以更新其他 subview 。 应该始终可以垂直滚动 UIScrollView。
第一个实验:
我尝试将透明的 UIView 添加到覆盖 UIScrollView 的 ViewController。 但是,即使直接引用 View1,触摸也不会被转发。
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.chartReference touchesBegan:touches withEvent:event];
}
无论如何,我不太确定这是否是实现此目标的正确方法。
第二个实验:
在 UIScrollView 的图表 subview 上禁用 userInteraction,并将我自己的捏合和平移手势(在 UIViewController 中)添加到 UIScrollView。
问题; 1. UIScrollView 不再滚动。 2、如何将这些手势转发给View1?
恐怕我现在无法提供更多示例代码,因为还没有太多相关代码可以展示。
编辑: 实验二的小记; 手势识别器已添加如下;
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];
pinchGestureRecognizer.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:pinchGestureRecognizer];
已启用 UIViewController 上的同步手势识别;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
编辑:
实验 2 的问题 2 已解决。我没有为平移/捏合手势设置正确的代表。哦!
剩下的就是如何转发捏/平移手势。
最佳答案
您即将在其他 View 之上放置一个透明 View 。但是,您需要重写另一种方法。
您想在透明 View 上覆盖 hitTest:withEvent。在遍历响应链以查看哪个 View 处理特定区域中的触摸时使用此方法。如果 View 处理了该触摸,它会返回 Itself。如果它想将它传递给它下面的下一个 View ,它返回 nil。如果它知道另一个 View 处理该触摸,它可以返回该 View 。
因此,在您的情况下,如果该点位于顶部透明 View 的目标区域中,则返回 view1。然后应调用 View1 的手势识别器。
示例:
InterceptorView 是一个位于 scrollView 之上的透明 View 。 TargetView 是 scrollView 内部的一个 View ,并附加了一个 TapGestureRecognizer。
class InterceptorView: UIView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@IBOutlet weak var targetView1: UIView?
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
print("[Interceptor] Testing point: \(point) ")
if self.pointInside(point, withEvent: event) {
println("Hit")
return targetView1
}
else {
println()
return nil;
}
}
}
--
class TargetView: UIView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@IBAction func handleGesture(gestureRecognizer: UIGestureRecognizer) {
let location = gestureRecognizer.locationInView(self)
print("[TargetView] Got gesture. Location \(location) ")
if (pointInside(location, withEvent: nil)) {
println("Inside");
}
else {
println("Outside");
}
}
}
这是项目: https://github.com/annabd351/GestureForwarding
(里面还有一些其他的东西,但它有效!)
关于ios - 带有触摸拦截器的 UIScrollView 用于 contentSize 以控制 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27060966/
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
这里有一个很好的答案解释了如何在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返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做
假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而
我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom
当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question