iOS小Demo1:星星評級效果

前言

早上的時光總是很漫長,距上班還有兩個小時,睡不著覺來搞點事情做,寫了一個星星評級的小demo,實現(xiàn)的比較簡單,哈哈,話不多說。

實現(xiàn)的原理

我們在很多商城類的app上面都會看到這種效果,在完成一個商品交易之后,會有個售后評分的頁面,上面是你對本次交易的評級。

22C268C4F7CC9F23A05694207545BDB6.png

我的實現(xiàn)原理非常的簡單:就是在一個視圖上面添加一個相同的視圖,然后通過view的clipsToBounds屬性,通過touch方法改變上面view的width即可。方式很簡單,我就直接粘貼代碼了(星星的圖片是我自己用sketch做的,可能有點丑..哈哈哈)。

具體代碼實現(xiàn):

#import "SHStarView.h"

@interface SHStarView ()

@property (nonatomic,strong) UIView *foregroundView;

@property (nonatomic,assign) NSInteger starNum;

@end

@implementation SHStarView

static NSString *normalName = @"star_nomal";
static NSString *selectName = @"star_selecte";


#pragma mark --- lazz --
-(UIView *)foregroundView{
    if (!_foregroundView) {
        _foregroundView = [UIView new];
        _foregroundView.clipsToBounds = YES;
        [self addSubview:_foregroundView];
    }
    
    return _foregroundView;
}


-(instancetype)initWithFrame:(CGRect)frame starNum:(NSInteger)starNum{
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor redColor];
        _starNum = starNum;
        [self setupSubviews];
    }
    
    return self;
}



-(void)setupSubviews{

    CGRect frame = self.bounds;
    CGFloat imageH = frame.size.width / self.starNum;
    CGFloat imageY = (frame.size.height - imageH) * 0.5;
    for (int i = 0; i < self.starNum; i ++) {
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:normalName]];
       // imageView.contentMode = UIViewContentModeCenter;
        imageView.frame = CGRectMake(i * (frame.size.width / self.starNum) , imageY ,imageH, imageH);
        [self addSubview:imageView];
    }
}


-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSSet *allTouches = [event allTouches];    //返回與當前接收者有關(guān)的所有的觸摸對象
    UITouch *touch = [allTouches anyObject];   //視圖中的所有對象
    CGPoint point = [touch locationInView:[touch view]];
    if (CGRectContainsPoint(self.bounds, point)) {
        [self changeStarColor:point];
    }
}


-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSSet *allTouches = [event allTouches];    //返回與當前接收者有關(guān)的所有的觸摸對象
    UITouch *touch = [allTouches anyObject];   //視圖中的所有對象
    CGPoint point = [touch locationInView:[touch view]];
    if (CGRectContainsPoint(self.bounds, point)) {
        [self changeStarColor:point];
    }
}



-(void)changeStarColor:(CGPoint)point{
    CGRect frame = self.bounds;

    CGFloat imageH = frame.size.width / self.starNum;
    CGFloat imageY = (frame.size.height - imageH) * 0.5;
    for (int i = 0; i < self.starNum; i ++) {
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:selectName]];
        
        imageView.frame = CGRectMake(i * (frame.size.width / self.starNum) , imageY ,imageH, imageH);
        [self.foregroundView addSubview:imageView];
    }
    
    self.foregroundView.frame = CGRectMake(0, 0, point.x,frame.size.height);
  
}

.h文件:

#import <UIKit/UIKit.h>

@interface SHStarView : UIView



-(instancetype)initWithFrame:(CGRect)frame starNum:(NSInteger)starNum;


@end

效果:

星星截屏.png

圖片資源:

star_nomal@2x.png
star_nomal@3x.png
star_selecte@2x.png
star_selecte@3x.png

第二種實現(xiàn)方法

最近在看coreGraphics框架的東西,其實用這個畫圖的框架也能實現(xiàn)上面的功能,這個部分的代碼如下:

@implementation SHStarView{
    int _currentStar;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    [super drawRect:rect];
    
    //star_selecte  star_nomal
    CGFloat starHeight = self.bounds.size.height;
    CGImageCreateWithImageInRect([[UIImage imageNamed:@"star_selecte"] CGImage], CGRectMake(0, 0, starHeight, starHeight));
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
    CGContextScaleCTM(context, 1, -1);
    
    for (int i = 0; i < 5; i ++) {
        CGRect imageRect = CGRectMake(starHeight * i, 0, starHeight, starHeight);
        CGContextDrawImage(context, imageRect, [[UIImage imageNamed:@"star_nomal"] CGImage]);
    }
    
    for (int i = 0; i < (int)_currentStar; i++) {
        if (i < 5) {
            CGRect imageRect = CGRectMake(starHeight * i, 0, starHeight, starHeight);
            
            CGContextDrawImage(context, imageRect, [[UIImage imageNamed:@"star_selecte"] CGImage]);
        }
        
    }
    
    CGContextRestoreGState(context);
    
}


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"touch begin");
    
    CGPoint point = [[touches anyObject] locationInView:self];
    
    CGFloat count = point.x / self.bounds.size.height;
    
    CGFloat sum = count > (int)count + .5 ? (int)count + 1 : (int)count + .5;
    
    if (sum != _currentStar) {
        
        _currentStar = sum;
        
        [self setNeedsDisplay];
    }
}

我在上面寫死了五顆星星,可以自己調(diào)整.這個原理就是運用了coreGraphics框架中的CGContextDrawImage方法.也是很簡單.

swift版的代碼如下:

import UIKit

class SHStarView: UIView {
    
    var starNun : NSInteger!
    
    var foregroundView : UIView! = {
        let view = UIView.init()
        view.clipsToBounds = true
        view.backgroundColor = UIColor.clear
        return view
        
    }()
    
    
    //自定義初始化方法:
    init(_ frame: CGRect , _ starNum: NSInteger) {
        super.init(frame: frame)
        self.starNun = starNum;
        self.backgroundColor = UIColor.red
        
        //加載子視圖
        setupSubviews()
        
    }

    
    
    func setupSubviews() {
        
        let frame : CGRect = self.bounds
        let imageH : CGFloat = frame.size.width / CGFloat(self.starNun);
        let imageY : CGFloat = (frame.size.height - imageH) * 0.5
        
        
        for i in 0..<self.starNun {
            let imageView = UIImageView.init(image: UIImage.init(named: "star_nomal"))
            imageView.frame = CGRect.init(x: CGFloat(i) * (frame.size.width / CGFloat(self.starNun)), y: imageY, width:imageH , height: imageH)
            self.addSubview(imageView)
        }
        
        //加載前面的視圖
        self.addSubview(foregroundView)
        
    }
    
    required init?(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
    }

    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
             let t : UITouch = touch as! UITouch
             let point = t.location(in: self)
             if self.bounds.contains(point) {
                changeStarColor(point: point)
            }
            
        }
    }
    
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
            let t : UITouch = touch as! UITouch
            let point = t.location(in: self)
            if self.bounds.contains(point) {
                changeStarColor(point: point)
            }
            
        }

        
    }
    
    //改變坐標
    func changeStarColor(point : CGPoint) {
        //先移除,再創(chuàng)建
        for subview in self.foregroundView.subviews {
            subview.removeFromSuperview()
        }
        
        let frame : CGRect = self.bounds
        let imageH : CGFloat = frame.size.width / CGFloat(self.starNun);
        let imageY : CGFloat = (frame.size.height - imageH) * 0.5
        
        for i in 0..<self.starNun {
            let imageView = UIImageView.init(image: UIImage.init(named: "star_selecte"))
            imageView.frame = CGRect.init(x: CGFloat(i) * (frame.size.width / CGFloat(self.starNun)), y: imageY, width:imageH , height: imageH)
            self.foregroundView.addSubview(imageView)
        }
        
        
        UIView.animate(withDuration: 0.3) {
            self.foregroundView.frame = CGRect.init(x: 0, y: 0, width: point.x, height: frame.size.height)
        }
        
    
    }
    
    

大家加油??!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,777評論 25 709
  • 愛是自私的,不去占有就不是愛。如果占有只是欲念的話,而得不到硬去占有,便是妄念。在妄念里疼痛,最要不得,往往都是自...
    星座知閱讀 953評論 0 0
  • 從前有個笑話國,盛產(chǎn)笑話和笑話人,每天太陽從西邊認真的升起,帶著笑臉,發(fā)出光芒,照到笑話人的臉上,笑話人起床的時間...
    德沛閱讀 2,615評論 11 30
  • 我已經(jīng)不了解你的最近生活了,我也不再那樣感興趣,我也不期望自己會在你心里留下怎樣的印象,不會想象在你心里占著怎樣的...
    離離離離曉閱讀 877評論 0 3

友情鏈接更多精彩內(nèi)容