Создать представление витрины на панели вкладок xcode

#ios #objective-c #xcode #uiview

#iOS #objective-c #xcode #uiview

Вопрос:

Я пытаюсь создать свой собственный пользовательский вид витрины, в котором у меня есть левая кнопка, правая кнопка и вид панели вкладок.

Я хочу выделить кнопки круглым кружком вокруг них. Я могу создать один круг вокруг моей кнопки с помощью подкласса UIView, но то, что я делаю, чтобы пользователь провел пальцем слева направо, изменит круг на правую кнопку, а левую кнопку скроет. Вот мой подкласс UIView

//———. h класс

 #import <UIKit/UIKit.h>

@interface IntroView : UIView
- (void)drawRect:(CGRect)rect withBtnRect:(CGRect)btnrect ;

@end
  

//——. m class

 #import "IntroView.h"

@implementation IntroView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }


   self.backgroundColor=   [[UIColor blackColor] colorWithAlphaComponent:0.3];

     return self;
}



- (void)drawRect:(CGRect)rect  {


   CGRect   maskRect= CGRectMake(5, 5, 100, 100);//set and pass this maskRect


    CGRect rBounds = self.bounds;
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Fill background with 40% gray
    CGContextSetFillColorWithColor(context, [[[UIColor grayColor] colorWithAlphaComponent:0.4] CGColor]);
    CGContextFillRect(context, rBounds);

    // Draw the window 'frame'
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
    CGContextSetLineWidth(context,2);
    CGContextStrokeEllipseInRect(context, maskRect);

    // make the window transparent
    CGContextSetBlendMode(context, kCGBlendModeClear);
    CGContextFillEllipseInRect (context, maskRect);

  }




/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end
  

И внутри моего первого представления на панели вкладок я вызываю с помощью

 #import "IntroView.h"
  

затем

 - (void)viewDidLoad
{
    IntroView *vw_intro=[[IntroView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
    vw_intro.tag=1000;     
     [self.view addSubview:vw_intro];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
  

Вот мой вывод

введите описание изображения здесь

И ожидаемый результат на слайде справа налево, и так или наоборот (как мы делаем в библиотеке showcase Android)

введите описание изображения здесь

Ответ №1:

Во внутреннем просмотре.h

 #import <UIKit/UIKit.h>

@interface IntroView : UIView
- (id)initWithFrame:(CGRect)frame introElements:(NSArray *)iElements;
- (void)showIntro;
@end
  

Во внутреннем просмотре.m

 #import "IntroView.h"

@implementation IntroView
{
    CAShapeLayer *mask;
    NSArray *introElements;
    NSUInteger currentIndex;
}

- (id)initWithFrame:(CGRect)frame introElements:(NSArray *)iElements
{
    self = [super initWithFrame:frame];
    if (self) {

        // Initialization code

        introElements = iElements;

        mask = [CAShapeLayer layer];
        [mask setFillColor:[[UIColor grayColor] colorWithAlphaComponent:0.8f].CGColor];
        [mask setFillRule:kCAFillRuleEvenOdd];
        [self.layer addSublayer:mask];

        UISwipeGestureRecognizer *swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(userDidSwipe)];
        swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
        [self addGestureRecognizer:swipeGestureRecognizer];
    }

    return self;
}

- (void)userDidSwipe
{
    [self showIntroAtIndex:currentIndex 1];
}

- (void)showIntro
{
    //Initial index by default
    [self showIntroAtIndex:0];
}

- (void)showIntroAtIndex:(NSUInteger)index
{
    currentIndex = index;

    CGRect rect = [[introElements objectAtIndex:index] CGRectValue];

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.bounds];
    UIBezierPath *elementPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:3.0f];
    [maskPath appendPath:elementPath];

    // Animate
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    animation.duration = 0.3f;
    animation.fromValue = (__bridge id)(mask.path);
    animation.toValue = (__bridge id)(maskPath.CGPath);
    [mask addAnimation:animation forKey:@"path"];
    mask.path = maskPath.CGPath;
}
  

В ViewController

 - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSArray *viewElements = [NSArray arrayWithObjects:[NSValue valueWithCGRect:button1.frame],[NSValue valueWithCGRect:button2.frame], nil];

    IntroView *introView = [[IntroView alloc]initWithFrame:self.view.bounds introElements:viewElements];
    [self.view addSubview:introView];
    [introView showIntro];
}
  

Примечание: я выделил рамку UIControl, если вам нужно выделить круг, обновите изменения в CGRect.

Комментарии:

1. спасибо за красивый и быстрый ответ, я скоро преобразоваю его в circle и опубликую