iOS開發(fā),UISlider滑塊不靈敏問題以及在UIScrollView上添加Slider造成手勢(shì)沖突問題心得

前言

最近在做項(xiàng)目時(shí)候有如下這樣一個(gè)界面


1.png

這個(gè)頁(yè)面涉及到視頻播放拖動(dòng)進(jìn)度條的需求,測(cè)試那邊提過來(lái)的bug是進(jìn)度條滑塊不夠靈敏,交互的時(shí)候很難響應(yīng)用戶的操作.苦逼碼農(nóng)一枚,提了bug就得改啊.

正文

在網(wǎng)上看了很多關(guān)于這方面的處理,總結(jié)了下大致3種方法

  • 一種是直接改變滑塊圖片的大小.但是在項(xiàng)目中有時(shí)為了整體風(fēng)格的統(tǒng)一和樣式匹配.不方便修改圖片大小.所以個(gè)人不是很喜歡這個(gè)解決方法.
  • 第二種,是繼承UISlider重寫如下方法,細(xì)微的擴(kuò)展一下滑塊的響應(yīng)范圍
背景:由于UI給的thumbImage圖片過小,默認(rèn)UISlider開始拖動(dòng)的手勢(shì)范圍只有thumbImage的大小之內(nèi).為了解決這個(gè)問題需要?jiǎng)?chuàng)建一個(gè)子類繼承于UISlider.重寫其中的方法:
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
{
//y軸方向改變手勢(shì)范圍
    rect.origin.y = rect.origin.y - 10;
    rect.size.height = rect.size.height + 20;
    return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], 10 ,10);
}
將會(huì)增加Y軸方向thumbImage的觸控范圍

這個(gè)修改的偏移數(shù)值,我還沒有做深入研究,好像改太大了的話,滑塊會(huì)消失.我打印了下bounds和rect好像相差的就是10.所以估計(jì)這里的偏移數(shù)值不是隨便給的,最好不要隨便改.

這個(gè)方法,我試了一下,效果有,但是不明顯,需求不高的情況下可以就用這個(gè)方法

*第三種方法,我認(rèn)為是效果最好的,需要繼承UISlider重寫如下方法

#define SLIDER_X_BOUND 30
#define SLIDER_Y_BOUND 40

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value;
{

    rect.origin.x = rect.origin.x;
    rect.size.width = rect.size.width;
    CGRect result = [super thumbRectForBounds:bounds trackRect:rect value:value];
//記錄下最終的frame
    lastBounds = result;
    return result;
}
//檢查點(diǎn)擊事件點(diǎn)擊范圍是否能夠交給self處理
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//調(diào)用父類方法,找到能夠處理event的view
    UIView* result = [super hitTest:point withEvent:event];
    if (result != self) {
        /*如果這個(gè)view不是self,我們給slider擴(kuò)充一下響應(yīng)范圍,
          這里的擴(kuò)充范圍數(shù)據(jù)就可以自己設(shè)置了
        */
        if ((point.y >= -15) &&
            (point.y < (lastBounds.size.height + SLIDER_Y_BOUND)) &&
            (point.x >= 0 && point.x < CGRectGetWidth(self.bounds))) {
            //如果在擴(kuò)充的范圍類,就將event的處理權(quán)交給self
            result = self;
        }
    }
    //否則,返回能夠處理的view
    return result;
}
//檢查是點(diǎn)擊事件的點(diǎn)是否在slider范圍內(nèi)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    //調(diào)用父類判斷
    BOOL result = [super pointInside:point withEvent:event];
    
    if (!result) {
        //同理,如果不在slider范圍類,擴(kuò)充響應(yīng)范圍
        if ((point.x >= (lastBounds.origin.x - SLIDER_X_BOUND)) && (point.x <= (lastBounds.origin.x + lastBounds.size.width + SLIDER_X_BOUND))
            && (point.y >= -SLIDER_Y_BOUND) && (point.y < (lastBounds.size.height + SLIDER_Y_BOUND))) {
            //在擴(kuò)充范圍內(nèi),返回yes
            result = YES;
        }
    }
    
    //NSLog(@"UISlider(%d).pointInside: (%f, %f) result=%d", self, point.x, point.y, result);
    //否則返回父類的結(jié)果
    return result;
}

對(duì)以上重寫方法有疑問的,或則不是很了解的,請(qǐng)移駕該篇文章事件處理,響應(yīng)者鏈條

通過上文的方法,基本就可以解決滑塊不靈敏的問題了而且效果不錯(cuò).當(dāng)然重寫方法不一定非要這么寫不可,可以根據(jù)項(xiàng)目需求和每個(gè)人的理解以及技術(shù)水準(zhǔn)不一樣.標(biāo)準(zhǔn)不是唯一的.

看似問題解決了,我終于可以告訴測(cè)試我的bug解決了.然而天不遂人愿.在測(cè)試demo上一切no problem.但當(dāng)我運(yùn)用到項(xiàng)目中問題出現(xiàn)了.滑塊給人的感覺還是不是很靈敏.不能直接用手指觸碰到滑塊立馬滑動(dòng),必須要按住一會(huì)才能很好的滑動(dòng).

這個(gè)問題困擾好久,最后感謝這篇文章關(guān)于ScrollerView的一些小心得

2.png

這個(gè)界面頂部有一行tab導(dǎo)航條,所以這個(gè)界面是需要支持左右滑動(dòng)切換tab導(dǎo)航條的.這個(gè)功能當(dāng)然是基于scrollView做的,追根究底.還是事件響應(yīng)處理的問題

UIScrollerView中添加了一個(gè)UISlider的組件凹炸,在手勢(shì)滑動(dòng)的過程中卫病,很難滑動(dòng)到UISlider這個(gè)控件,經(jīng)常是滑動(dòng)的時(shí)候UIScrollerView進(jìn)行了滾動(dòng)特咆,

而UISlider這個(gè)控件沒有滑動(dòng),讓人很抓狂。

下面引用一下前輩的總結(jié)笑诅,因?yàn)樽约河X得沒有他總結(jié)的詳細(xì)

UIScrollView重載了hitTest方法吐辙,當(dāng)手指touch的時(shí)候宣决,UIScrollView會(huì)攔截所有event,然后等待150ms,在這段時(shí)間內(nèi)昏苏,如果沒有手指沒有移動(dòng)尊沸,當(dāng)時(shí)間結(jié)束時(shí)威沫,UIScrollView會(huì)發(fā)送tracking event到子視圖上,并且自身不滑動(dòng)洼专。在時(shí)間結(jié)束前棒掠,手指發(fā)生了移動(dòng),那么UIScrollView就會(huì)進(jìn)行滑動(dòng)屁商,從而取消發(fā)送tracking烟很。

總結(jié)以上所述,總算略有眉目.于是我為這個(gè)界面寫了一個(gè)UIScrollView的類擴(kuò)展重寫了方法:

看來(lái)是UIScrollView的問題。直接拖動(dòng)UISlider蜡镶,此時(shí)touch時(shí)間在150ms以內(nèi)雾袱,UIScrollView會(huì)認(rèn)為是拖動(dòng)自己,從而攔截了event官还,導(dǎo)致UISlider接受不到滑動(dòng)的event芹橡。但是只要按住UISlider一會(huì)再拖動(dòng),此時(shí)此時(shí)touch時(shí)間超過150ms望伦,因此滑動(dòng)的event會(huì)發(fā)送到UISlider上林说。

期間試過幾種方法,只有一種可行屯伞,就是重寫UIScrollView的hitTest方法:當(dāng)滑動(dòng)UISlider時(shí)腿箩,使UIScrollView不可滑動(dòng)。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    
    
    /*
     直接拖動(dòng)UISlider劣摇,此時(shí)touch時(shí)間在150ms以內(nèi)度秘,UIScrollView會(huì)認(rèn)為是拖動(dòng)自己,從而攔截了event饵撑,導(dǎo)致UISlider接受不到滑動(dòng)的event剑梳。但是只要按住UISlider一會(huì)再拖動(dòng),此時(shí)此時(shí)touch時(shí)間超過150ms滑潘,因此滑動(dòng)的event會(huì)發(fā)送到UISlider上垢乙。
    */
    UIView *view = [super hitTest:point withEvent:event];
    
    if([view isKindOfClass:[UISlider class]])
    {
        //如果響應(yīng)view是UISlider,則scrollview禁止滑動(dòng)
        self.scrollEnabled = NO;
    }
    else
    {   //如果不是,則恢復(fù)滑動(dòng)
        self.scrollEnabled = YES;
    }
    return view;
}

OK,cmd + R運(yùn)行項(xiàng)目,大功告成!!!

寫在最后

參考:
iOS UISlider滑動(dòng)塊觸摸范圍調(diào)整變大
關(guān)于UISlider的拖動(dòng)手勢(shì)不靈敏的解決方法
UIScorllView心得

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市语卤,隨后出現(xiàn)的幾起案子追逮,更是在濱河造成了極大的恐慌,老刑警劉巖粹舵,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钮孵,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡眼滤,警方通過查閱死者的電腦和手機(jī)巴席,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诅需,“玉大人漾唉,你說我怎么就攤上這事荧库。” “怎么了赵刑?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵分衫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我般此,道長(zhǎng)蚪战,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任铐懊,我火速辦了婚禮屎勘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘居扒。我一直安慰自己,他們只是感情好丑慎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布喜喂。 她就那樣靜靜地躺著,像睡著了一般竿裂。 火紅的嫁衣襯著肌膚如雪玉吁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天腻异,我揣著相機(jī)與錄音进副,去河邊找鬼。 笑死悔常,一個(gè)胖子當(dāng)著我的面吹牛影斑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播机打,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼矫户,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了残邀?” 一聲冷哼從身側(cè)響起皆辽,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芥挣,沒想到半個(gè)月后驱闷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡空免,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年空另,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹋砚。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痹换,死狀恐怖征字,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娇豫,我是刑警寧澤匙姜,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站冯痢,受9級(jí)特大地震影響氮昧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜浦楣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一袖肥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧振劳,春花似錦椎组、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弱贼,卻和暖如春蒸苇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吮旅。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工溪烤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庇勃。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓檬嘀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親责嚷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枪眉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容