問題描述
請有人幫忙解決一個菜鳥嗎?我已經(jīng)在各種論壇上發(fā)布了這個問題并且沒有收到任何答案,而許多其他答案的搜索都出現(xiàn)了 stackOverflow,所以我希望這是這個地方.
Please can someone help sort a noob out? I've posted this problem on various forums and received no answers, while many searches for other answers have turned up stackOverflow, so I'm hoping this is the place.
我有一個 BeachView.h(UIScrollView 的子類,沙灘的圖片),上面覆蓋著隨機數(shù)的 Stone.h(UIImageView 的子類,石頭的隨機 PNG,userInteractionEnabled = YES 接受觸摸).
I've got a BeachView.h (subclass of UIScrollView, picture of a sandy beach) covered with a random number of Stone.h (subclass of UIImageView, a random PNG of a stone, userInteractionEnabled = YES to accept touches).
如果用戶在海灘上觸摸和移動,它應該滾動.如果用戶點擊石頭,它應該調(diào)用方法touchedStone".如果用戶點擊沒有石頭的海灘,它應該調(diào)用方法touchedBeach".
If the user touches and moves on the beach, it should scroll. If the user taps a stone, it should call method "touchedStone". If the user taps the beach where there is no stone, it should call method "touchedBeach".
現(xiàn)在,我意識到這聽起來很簡單.每個人都告訴我,如果 UIScrollView 上有什么東西可以接受觸摸,它應該將控制權(quán)傳遞給它.所以當我觸摸和拖動時,它應該滾動;但是如果我點擊,它在石頭上,它應該忽略海灘水龍頭并接受石頭水龍頭,是嗎?
Now, I realize this sounds dead simple. Everyone and everything tells me that if there's something on a UIScrollView that accepts touches that it should pass control on to it. So when I touch and drag, it should scroll; but if I tap, and it's on a stone, it should ignore beach taps and accept stone taps, yes?
但是,似乎兩個視圖都接受了點擊并調(diào)用了touchedStone 和touchedBeach.此外,海灘水龍頭首先發(fā)生,所以我什至不能輸入如果接觸石頭,則不要運行接觸海灘"類型的標志.
However, it seems that both views are accepting the tap and calling both touchedStone AND touchedBeach. Furthermore, the beach tap occurs first, so I can't even put in a "if touchedStone then don't run touchedBeach" type flag.
這里有一些代碼.在 BeachView.m
Here's some code. On BeachView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.decelerating) { didScroll = YES; }
else { didScroll = NO; }
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
NSLog(@"touched beach = %@", [touch view]);
lastTouch = touchLocation;
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
didScroll = YES;
[super touchesMoved:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (didScroll == NO && isPaused == NO) {
[self touchedBeach:YES location:lastTouch];
}
[super touchesEnded:touches withEvent:event];
}
在石頭上.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[parent stoneWasTouched]; // parent = ivar pointing from stone to beachview
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
NSLog(@"touched stone = %@", [touch view]);
[parent touchedStone:YES location:touchLocation];
}
敲擊后,我的 NSLog 如下所示:
After a stone tap, My NSLog looks like this:
Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched Stone = <Stone: 0x1480c0>
ran touchedStone
所以實際上兩者都在運行.更奇怪的是,如果我將 touchesBegan 和 touchesEnded 從 Stone.m 中取出,但保留 userInteractionEnabled = YES,則 beachView 會自行注冊這兩個觸摸,但將 Stone 作為它觸摸的視圖返回(第二次).
So it's actually running both. What's even stranger is if I take the touchesBegan and touchesEnded out of Stone.m but leave userInteractionEnabled = YES, the beachView registers both touches itself, but returns the Stone as the view it touched (the second time).
Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched beach = <Stone: 0x1480c0>
ran touchedBeach
所以請,我這幾天一直在努力解決這個問題.我怎樣才能使敲擊的石頭只調(diào)用touchedStone,而敲擊的海灘只調(diào)用touchedBeach?我哪里錯了?
So PLEASE, I've been trying to sort this for days. How do I make it so a tapped stone calls only touchedStone and a tapped beach calls only touchedBeach? Where am I going wrong?
推薦答案
在 iPhone OS 3.0 之前,UIScrollView 的 hitTest:withEvent: 方法總是返回 self 以便它直接接收 UIEvent,只有在當它確定它與滾動或縮放無關(guān)時.
Prior to iPhone OS 3.0, the UIScrollView's hitTest:withEvent: method always returns self so that it receives the UIEvent directly, only forwarding it to the appropriate subview if and when it determines it's not related to scrolling or zooming.
我無法對 iPhone OS 3.0 發(fā)表評論,因為它在 NDA 下,但請查看您的iPhone SDK Release notes for iPhone OS 3.0 beta 5":)
I couldn't really comment on iPhone OS 3.0 as it's under NDA, but check your "iPhone SDK Release notes for iPhone OS 3.0 beta 5" :)
如果您需要定位 3.0 之前的版本,您可以在 BeachView 中覆蓋 hitTest:withEvent: 并設(shè)置一個標志以在 CGPoint 實際上位于石頭中時忽略下一次海灘觸摸.
If you need to target pre-3.0, you could override hitTest:withEvent: in BeachView and set a flag to ignore the next beach touch if the CGPoint is actually in a stone.
但是您是否嘗試過簡單地將對 [super touches*:withEvent:] 的調(diào)用從覆蓋方法的末尾移到開頭?這可能會導致先敲擊石頭.
But have you tried simply moving your calls to [super touches*:withEvent:] from the end of your overridden methods to the start? This might cause the stone tap to occur first.
這篇關(guān)于UIScrollView 觸摸與子視圖觸摸的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!