如何突出像Apple一样的UIView

时间:2014-01-18 22:10:38

标签: uiview uibutton highlight

当用户触摸UIButton时,它会变灰。什么苹果能做到这样的效果?当突出显示我的自定义UIButton时,我需要相同的效果。

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    AppDelegate* appDelegate=(AppDelegate*)[UIApplication sharedApplication].delegate;
    if ([keyPath isEqualToString:@"highlighted"]){
        UIButton *button = object;
        if (button.isHighlighted) {
            self.backgroundColor=[UIColor colorWithRed:36.0/255.0 green:153.0/255.0 blue:116.0/255.0 alpha:1];
        }else{
            self.backgroundColor=appDelegate.currentAppColor;
        }
    }
}

我正在使用此代码,但更改背景颜色不会影响任何子视图。我也需要它们变灰。

7 个答案:

答案 0 :(得分:5)

我认为没有一个简单或明确的答案。

  
    

声明:     这个答案中的所有代码都是从头顶写的,所以请原谅错误。

  

我建议做这样的事情:

提案1 :降低所有视图的子视图的不透明度,这不会影响颜色......

-(void)buttonTouched{

    for(UIView *subview in self.subviews){

        subview.alpha = 0.5;

    }

}

提案2 (未经测试):尝试通过手动操作来覆盖所有子视图(缺点:您还必须手动设置颜色,如果是的话,这将是疯狂的不是单色的):

-(void)buttonTouched{

    for(UIView *subview in self.subviews){

        if([subview respondsToSelector:@selector(setBackgroundColor:)]){ 
            //for generic views - changes UILabel's backgroundColor too, though
            subview.backgroundColor = [UIColor grayColor];
        }

        if([subview respondsToSelector:@selector(setTextColor:)]){ 
            //reverse effect of upper if statement(if needed)
            subview.backgroundColor = [UIColor clearColor];
            subview.textColor = [UIColor grayColor];
        }

    }

}

这是非常糟糕的设计,可能会导致很多问题,但它可能对您有所帮助。上面的例子需要很多改进,我只是想给你一个提示。你必须恢复touchesEnded:方法中的颜色。也许它可以帮助你...

提案3 :用透明视图覆盖整个视图(如果是矩形)

-(void)buttonTouched{

    UIView *overlay = [[UIView alloc]initWithFrame:self.bounds];
    overlay.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.5];
    [self addSubview: overlay];

}

当用户释放手指时,您必须将其删除。

提案4 :另一种选择是创建当前视图的位图并根据自己的喜好修改像素,这是相当多的工作,因此我将在此处省略代码。

Apple可能会将最后两款混合使用。当触摸按钮时,它将覆盖像素并在具有alpha分量的每个像素上覆盖灰色像素。

我希望我能提供帮助。

答案 1 :(得分:4)

我知道这是一个老问题。但是,如果有人仍在寻找通用的触摸突出显示解决方案,那么我已经创建了一个小类来解决这个问题。

https://github.com/mta452/UIView-TouchHighlighting

<强>用法:

只需在视图控制器中导入类别,然后在viewDidLoad中添加以下行。

buttonView.touchHighlightingStyle = MTHighlightingStyleHollowDarkOverlay;

不同的突出显示样式:

Screenshot

答案 2 :(得分:2)

例如,您可以使用这样的自定义视图:

class HighlightView: UIView {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        DispatchQueue.main.async {
            self.alpha = 1.0
            UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
                self.alpha = 0.5
            }, completion: nil)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        DispatchQueue.main.async {
            self.alpha = 0.5
            UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
                self.alpha = 1.0
            }, completion: nil)
        }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        DispatchQueue.main.async {
            self.alpha = 0.5
            UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
                self.alpha = 1.0
            }, completion: nil)
        }
    }
}

然后,您可以使用它代替UIView,并且每当单击它时,它都会更改其alpha值,因此看起来像是突出显示的。

答案 3 :(得分:1)

斯威夫特3:

在自定义UIView类

中覆盖touchesBegantouchesEnded回调
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.layer.backgroundColor = UIColor.white.cgColor
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.layer.backgroundColor = UIColor.gray.cgColor
}

或更好地使用投影而不是更改背景

CardView代码,但触及从https://github.com/aclissold/CardView

借来的事件
@IBDesignable
class CardView: UIView {

    @IBInspectable var cornerRadius: CGFloat = 5

    @IBInspectable var shadowOffsetWidth: Int = 0
    @IBInspectable var shadowOffsetHeight: Int = 1
    @IBInspectable var shadowColor: UIColor? = UIColor.black
    @IBInspectable var shadowOpacity: Float = 0.23

    override func layoutSubviews() {
        layer.cornerRadius = cornerRadius
        let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius)

        layer.masksToBounds = false
        layer.shadowColor = shadowColor?.cgColor
        layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight);
        layer.shadowOpacity = shadowOpacity
        layer.shadowPath = shadowPath.cgPath
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight * 2);

    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: 

    shadowOffsetHeight);
        }

    }

更新:

我还添加了touchesCancelled回调功能,以防止UIView卡在选定状态。

 override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight);
    } 

答案 4 :(得分:0)

结束此代码

maskView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
maskView.backgroundColor=[[UIColor blackColor]colorWithAlphaComponent:0.5];

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        if ([keyPath isEqualToString:@"highlighted"]){
            UIButton *button = object;
            if (button.isHighlighted) {
                [self addSubview:maskView];
            }else{
                [maskView removeFromSuperview];
            }
        }
    }

答案 5 :(得分:0)

想法:

  1. 要在其中触发触摸区域的添加按钮。

  2. 使用事件:向下触摸,内部向上触摸和外部向上

  3. 在“向下触摸”中设置了“突出显示”状态值,其他设置了“正常值”。

您可以使用情节提要IBAction或以编程方式进行。

示例代码(以编程方式):

- (void)viewDidLoad {
    [super viewDidLoad];

    firstView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
    firstView.backgroundColor = [UIColor blueColor];

    firstBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
    [firstBtn addTarget:self action:@selector(touchDownCollection) forControlEvents:UIControlEventTouchDown];
    [firstBtn addTarget:self action:@selector(touchUpInSideCollection) forControlEvents:UIControlEventTouchUpInside];
    [firstBtn addTarget:self action:@selector(touchUpOutSideCollection) forControlEvents:UIControlEventTouchUpOutside];

    [self.view addSubview:firstView];
    [self.view addSubview:firstBtn];

    //Need add: firstView.userInteractionEnabled = NO; if
    //[self.view addSubview:firstBtn];
    //[self.view addSubview:firstView];
}

- (void)touchDownCollection {
    // Highlight state value: alpha, background...
    firstView.alpha = 0.5;
}

- (void)touchUpInSideCollection {
    // Normal state value.
    firstView.alpha = 1.0;
}

- (void)touchUpOutSideCollection {
    // Normal state value.
    firstView.alpha = 1.0;
}

答案 6 :(得分:-1)

  1. 为您的UIView创建一个点按手势

    UITapGestureRecognizer* buttonViewTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(categoryButtonAction:)];
    
  2. 现在将以下定义添加到您的代码中。它会有一些类似于View的效果。

    -(void)touchGestureAction:(UIGestureRecognizer*)gesture
    {
        UIView * sender =  gesture.view;
    
        UIColor *color = sender.backgroundColor;
        sender.backgroundColor = [UIColor whiteColor];
        sender.alpha = 0.7;
    
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
    //  This will create flash effect
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            sender.backgroundColor = color;
            sender.alpha = 1.0;
        });
    }
    
  3. 这将创建一些与按钮触摸效果类似的效果。