UISlider突出显示不同拇指宽度的状态

far*_*ski 16 iphone uikit uislider ios

我正在尝试实现一个自定义UISlider(UISlider的子类),其行为方式与原始滑块类似,当它突出显示时,拇指周围会发出光晕.不过,我遇到了麻烦.

突出显示的拇指的(有效)宽度明显大于正常拇指(由于发光).如果我将透明像素填充添加到正常状态图像,以便两个图像具有相同的宽度,问题是正常状态拇指看起来永远不会到达轨道的末端(它确实到达结尾,但填充使得它看起来不然).

如果我使用thumbRectForBounds:来偏移拇指以正确地与轨道的开头对齐,它只会使问题在另一端变得更糟.

如果我保持两个图像只是它们需要的宽度(即,在正常状态下没有填充,并且两个宽度不同),我已经接近了.我可以在thumbRectForBounds中独立设置偏移量:基于UIControl.state,但看起来幕后有一些数学魔法.UISlider认为这两种状态的图像排列完美的唯一地方就是确切的中心.

看起来我可能需要实现一些数学运算,根据它沿着轨道的相对位置来确定高光状态的偏移.它需要在中心处具有零偏移y(UISlider将使两个图像居中,这意味着它们对齐).在极端情况下,它需要一个完全弥补发光的y偏移.在它之间需要插入y偏移量.

这似乎是很多工作来重新创建原生滑块所做的事情,所以也许我错过了一些明显的东西.

更新 当前解决方案

它不是完全可移植的,因为它会对添加的光晕大小做出一些假设.我正在添加带有图像的光晕而不是直接将其绘制到CALayer.我还没有测试过它的表现如何.

基本上我创建了一个正方形的图层,其尺寸是默认状态拇指图像的高度,以拇指为中心,然后绘制发光(仅发光,而不是带有发光的拇指的单独图像)完成高光状态图像)到图层.

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
  CGRect r = [super thumbRectForBounds:bounds trackRect:rect value:value];

  [thumbHighlightOverlayLayer removeFromSuperlayer];
  thumbHighlightOverlayLayer = [CALayer layer]; 

  int x = r.origin.x + (r.size.width / 2) - (r.size.height / 2);
  thumbHighlightOverlayLayer.frame = CGRectMake(x, r.origin.y, r.size.height, r.size.height);

  UIImage* thumbHighlightOverlayImage = [UIImage imageNamed:@"thumb-highlight"];
  thumbHighlightOverlayLayer.contents = (id)thumbHighlightOverlayImage.CGImage;

  switch (self.state) {
    case UIControlStateHighlighted:
      [[self layer] addSublayer:thumbHighlightOverlayLayer];
      break;
    default:
      break;
  }

  return r;
}
Run Code Online (Sandbox Code Playgroud)

Tej*_*lli 1

与其在图像中添加发光效果,不如动态添加它可能更好。您可以使用 CALayer 添加发光效果。

CAL层