Круговой UIView с изменяемым размером по центру

Я ищу способ создать CIRCULAR UIView с возможностью изменения размера и сохранением центра (см. изображение). Представление CIRCULAR в этом примере является подклассом UIView WCSDailyGoal.

ContainerView.m

- (void)createDailyGoalView
{
    _dailyGoalView = [[WCSDailyGoalView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    _dailyGoalView.delegate = self;
    _dailyGoalView.goal = 200;
    _dailyGoalView.center = self.view.center;
    [self.view addSubview:_dailyGoalView];
}

WCSDailyGoal.m

- (void)setGoal:(CGFloat)goal
{
    CGPoint saveCenter = self.center;
    CGRect newFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, goal, goal);
    self.frame = newFrame;
    self.layer.cornerRadius = goal / 2.0;
    self.center = saveCenter;
}

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


person WrightsCS    schedule 17.03.2015    source источник


Ответы (2)


Я смог добиться этого эффекта, создав пользовательский вид (следующий код быстрый):

class ResizableCircleView: UIView {

   var maxSize: CGFloat = 100
   var minSize: CGFloat = 10

   private var dragRecognizer: UIPanGestureRecognizer!
   private var currentScale: CGFloat = 1

   private var defaultSize: CGFloat { return frame.width / currentScale }

   override func layoutSubviews() {
      super.layoutSubviews()
      if dragRecognizer == nil{
         dragRecognizer = UIPanGestureRecognizer(target: self, action: "handleDrag:")
         addGestureRecognizer(dragRecognizer)
      }
      backgroundColor = UIColor.blackColor()
      layer.cornerRadius = frame.width / 2
      clipsToBounds = true
   }

   func handleDrag(recognizer: UIPanGestureRecognizer){
      let inTopArea = recognizer.locationInView(self).y < frame.height / 2
      let dy = recognizer.translationInView(self).y

      var newSize = frame.height + (inTopArea ? -1 : 1) * dy
      newSize = min(maxSize, newSize)
      newSize = max(minSize, newSize)
      currentScale = newSize/defaultSize
      transform = CGAffineTransformMakeScale(currentScale, currentScale)

      recognizer.setTranslation(CGPointZero, inView: self)
   }
}

Вы можете настроить максимальный и минимальный размеры, установив желаемые значения maxSize и minSize. Надеюсь, это поможет.

person Nikita Arkhipov    schedule 17.03.2015
comment
Вау, здорово! Ты спас мой день, @Nikita! - person Sonic Master; 27.07.2016

Из вашего вопроса не совсем понятно, чего вы хотите и в чем ваша проблема, но я попытаюсь ответить на него, основываясь на своих предположениях о том, что вы имеете в виду.

Во-первых, представление не должно управлять своей позицией. Контроллер представления или родительское представление в идеале должны находиться в viewDidLayoutSubviews или layoutSubviews в зависимости от ситуации. self.center = ... всегда делать неправильно, потому что точное положение центра представления зависит от размера и формы его родительского представления, а дочернее представление не должно знать такие вещи о своем родительском представлении. .

Во-вторых, не существует такого понятия, как «круглый» UIView. Вы можете сделать квадрат UIView и замаскировать его слой, чтобы он казался круглым, создав круг, используя CAShapeLayer с кругом в качестве контура, а затем используйте myView.layer.mask = circleShapeLayer, чтобы применить маску.

Для обработки взаимодействия используйте PanGestureRecognizer в родительском представлении. В gestureRecognizerShouldBegin определите, находится ли касание в правильном месте для начала взаимодействия (внутри круга? на радиусе круга? на радиусе круга вверху?), и верните YES или NO в зависимости от ситуации. В функции действия распознавателя жестов рассчитайте новый размер круга и установите размер кругового вида с помощью myView.bounds = CGRectMake(0, 0, 2*circleRadius, 2*circleRadius);.

Это должно делать то, что вам нужно.

person damian    schedule 26.03.2015