在 UISlider 中增加拇指“点击区域”

Posted

技术标签:

【中文标题】在 UISlider 中增加拇指“点击区域”【英文标题】:Increasing a thumbs "click area" in UISlider 【发布时间】:2013-08-11 22:35:41 【问题描述】:

我正在创建一个自定义 UISlider 并且想知道如何增加拇指图像的“点击区域”?下面的代码效果很好,除了拇指的“点击区域”保持不变。如果我没记错的话,我相信标准拇指区域是 19 像素?假设我想使用下面的代码将其增加到 35px,我需要采取哪些步骤?请记住,我根本不是这方面的专家。

编辑 下面的代码已更正,可以复制意大利面了!希望对你有帮助!

ma​​in.h

#import "MyUISlider.h"

@interface main : MLUIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIActionSheetDelegate, UIAlertViewDelegate, MFMailComposeViewControllerDelegate, UIGestureRecognizerDelegate, MLSearchTaskDelegate, MLDeactivateDelegate, MLReceiptDelegate>

  ..........



- (void)create_Custom_UISlider;

ma​​in.m

- (void)viewDidLoad


[self create_Custom_UISlider];
[self.view addSubview: customSlider];



- (void)create_Custom_UISlider

CGRect frame = CGRectMake(20.0, 320.0, 280, 0.0);


customSlider = [[MyUISlider alloc] initWithFrame:frame];

[customSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
// in case the parent view draws with a custom color or gradient, use a transparent color

customSlider.backgroundColor = [UIColor clearColor];

UIImage *stetchLeftTrack = [[UIImage imageNamed:@"blue_slider08.png"]
           stretchableImageWithLeftCapWidth: 10.0 topCapHeight:0.0];
UIImage *stetchRightTrack = [[UIImage imageNamed:@"blue_slider08.png"]
            stretchableImageWithLeftCapWidth: 260.0 topCapHeight:0.0];


[customSlider setThumbImage: [UIImage imageNamed:@"slider_button00"] forState:UIControlStateNormal];
[customSlider setMinimumTrackImage:stetchLeftTrack forState:UIControlStateNormal];
[customSlider setMaximumTrackImage:stetchRightTrack forState:UIControlStateNormal];


                    customSlider.minimumValue = 0.0;
                    customSlider.maximumValue = 1.0;
                    customSlider.continuous = NO;
                    customSlider.value = 0.00;



-(void) sliderAction: (UISlider *) sender

if(sender.value !=1.0)
 [sender setValue: 0.00 animated: YES];

else
[sender setValue 0.00 animated: YES];
 // add some code here depending on what you want to do!
  

EDIT(尝试使用下面的代码进行子类化)

MyUISlider.h

#import <UIKit/UIKit.h>

@interface MyUISlider : UISlider 



@end

MyUISlider.m

#import "MyUISlider.h"

@implementation MyUISlider



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



return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], 10 , 10);




@end

【问题讨论】:

在这里查看我对同一问题的工作示例:***.com/a/26316371/258931 Custom UISlider - Increase "hot spot" size的可能重复 【参考方案1】:

您必须在自定义 子类覆盖 thumbRectForBounds:trackRect:value:(而不是像在代码中那样自己调用该方法,这除了返回一个您甚至都懒得检索的值之外,什么都不做。

thumbRectForBounds:trackRect:value: 不是 set tumb rect 的方法,而是 get 它。滑块将在内部调用此 thumbRectForBounds:trackRect:value: 方法以知道在哪里绘制拇指图像,因此您需要覆盖它 - 如文档中所述 - 以返回您想要的 CGRect (这样它将是您希望的 35x35px )。

【讨论】:

我尝试了不同的方法,但都失败了。可能是因为我很坏并且做错了什么。我已经在上面编辑了我的代码,您能否展示(填写或修复代码)并展示您将如何完成它?如果没有,谢谢您的帮助。你至少给我指明了正确的方向...... 您拥有正确的代码结构。您只需要根据trackRectvalue 实现返回正确CGRect 的方法(因为拇指在不同的位置,当然取决于滑块值),如文档中所述。只需要做一些简单的数学运算。当然,在您的 create_Custom_UISlider 方法中写入 customSlider = [[MyUISlider alloc] initWithFrame:frame];,以实例化 MyUISlider 而不是标准的 UISlider 谢谢你回答阿里。我忘了将代码更改为 MyUISlider alloc.. 但我不明白我应该如何在方法中构造代码: - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float )价值 ?????? 返回有用的东西。我知道你不能给我确切的数字,但是如果你看看我的其余代码,你会在这个方法中加入什么?再次感谢您的帮助! 为什么不简单地依赖 super 实现,并简单地返回 CGRectInset([super thumbRectForBounds:bounds trackRect:rect value:value], -10, -10) 以获得比 UISlider 超类使用的矩形大 10x10 的矩形? thumbRectForBounds...的实现好像有错误。在CGRectInset 调用之前没有return 语句。你应该有:return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], -10 , -10);【参考方案2】:

已针对 Swift 3.0 和 iOS 10 更新

private func generateHandleImage(with color: UIColor) -> UIImage 
    let rect = CGRect(x: 0, y: 0, width: self.bounds.size.height + 20, height: self.bounds.size.height + 20)

    return UIGraphicsImageRenderer(size: rect.size).image  (imageContext) in
        imageContext.cgContext.setFillColor(color.cgColor)
        imageContext.cgContext.fill(rect.insetBy(dx: 10, dy: 10))
    

调用:

self.sliderView.setThumbImage(self.generateHandleImage(with: .white), for: .normal)

原答案:

到目前为止,最简单的方法就是增加拇指图像的大小,并在其周围设置不可见的边框:

- (UIImage *)generateHandleImageWithColor:(UIColor *)color

    CGRect rect = CGRectMake(0.0f, 0.0f, self.bounds.size.height + 20.f, self.bounds.size.height + 20.f);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.f);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, CGRectInset(rect, 10.f, 10.f));

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;

然后将此图像添加到滑块:

[self.sliderView setThumbImage:[self generateHandleImageWithColor:[UIColor redColor]] forState:UIControlStateNormal];

【讨论】:

很棒的答案!惊讶它没有更多的赞成票? 我添加了 Swift 3.0、ios 10 版本的 Objective-C 代码。像魅力一样工作! 这个答案(在 Swift 中)只为我生成并放置了图像。它并没有为我改变拇指的“点击区域”...... 对我来说,当值为 minimumValue 时,拇指不会与 UISlider 的左边缘对齐。因为 UISlider 为 thumbImage 的大小调整 minimumValue 位置。有解决这个问题的办法吗? 告诉我如果我想添加自定义图像怎么做【参考方案3】:

我也遇到了这个问题,通过覆盖解决了

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

方法。 你可以为那些你想被触摸的点返回 YES。

【讨论】:

【参考方案4】:

你可以查看我的双滑块project

总之,我实现了 hit 测试方法,因此调用了 beginTrackingWithTouch

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
    if (CGRectContainsPoint(self.leftHandler.frame, point) || CGRectContainsPoint(self.rightHandler.frame, point)) 
        return self;
    

    return [super hitTest:point withEvent:event];

查看class了解更多详情

【讨论】:

【参考方案5】:

为什么要使用自定义滑块,而您可以更改默认滑块的区域;)

看看这段代码,它对我来说增加了 UISlider 的触摸区域,希望它对你也有帮助

CGRect sliderFrame = yourSlider.frame;
sliderFrame.size.height = 70.0;
[yourSlider setFrame:sliderFrame];

【讨论】:

您可以将滑块设置为 1000 高,但拇指。仍然是相同的大小。

以上是关于在 UISlider 中增加拇指“点击区域”的主要内容,如果未能解决你的问题,请参考以下文章

Swift UISlider 删除拇指色调未完全加载的问题

在 Swift 中更改 UISlider 拇指的大小

如何读取 UISlider 拇指图像的大小

自定义 UISlider - 增加“热点”大小

调整 UISlider 拇指图像

UISlider 拇指移动而不接触拇指