Сдвиг фигуры из квадрата в треугольник и обратно

Форма

Мы можем начать с создания квадрата, используя структуру типа Shape и функцию пути, которая рисует наш квадрат и возвращает его:

Внутри нашего ContentView мы можем добавить нашу фигуру внутри GeometryReader. Это позволит нам придать нашей форме рамку, которая зависит от ширины экрана. Это заставит нашу фигуру выглядеть одинаково на всех устройствах в портретном режиме. Чтобы наша форма хорошо смотрелась в альбомном режиме, вы можете использовать функцию min, чтобы увидеть, какая из ширины и высоты меньше, а затем отрегулировать рамку, используя наименьшее значение.

Когда вы запустите код, вы найдете нашу квадратную форму. Если вы хотите добавить обводку к квадрату, вы можете получить ошибку компилятора (“Value of type ‘some View’ has no member ‘stroke.’”). Чтобы избежать этой ошибки, у нас может быть наложение той же формы с обводкой:

AnimatablePair

Теперь мы можем добавить приведенный ниже фрагмент кода к нашей фигуре. Этот код позволит нашей форме анимировать, постепенно изменяя значения divideByValue и multiplyByValue.

Например, если x = 1, то когда мы изменим его значение на x = 0, значение будет постепенно меняться 0,9 → 0,8 → 0,7 → 0,6… → 0,0.

Объявите две переменные состояния в нашем ContentView, чтобы передать их нашей фигуре. Сделайте divideByValue = 1 и multiplyByValue = 0.

Анимация

Значения x в наших первых двух линиях пути, которые мы добавили для нашей квадратной формы, приведены ниже:

path.addLine(to: CGPoint(x: 0, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))

Чтобы изменить нашу квадратную форму на треугольник, нам нужно изменить значения x на rect.maxX/2:

path.addLine(to: CGPoint(x: (rect.maxX / 2), y: rect.minY))
path.addLine(to: CGPoint(x: (rect.maxX / 2), y: rect.minY))

x нашей первой строки должен переключаться между x = 0 и x = rect.maxX /2 для создания обеих форм, а значение x во второй строке необходимо изменить с x = rect.maxX на rect.maxX /2.

Замените нашу функцию пути на приведенный ниже код. У нас будет divideByValue переключение между 1 и 2 и multiplyByValue между 0 и 1:

Теперь мы добавляем кнопку, которая изменит значения наших переменных состояния, которые мы объявили внутри нашего ContentView. Кнопка переключает свой текст между Square и Triangle, используя значение нашего multiplyByValue состояния:

Поскольку multiplyByValue находится внутри withAnimation, это сделает наш текст анимированным. Мы не хотим, чтобы это произошло, потому что перед переключением на слово Triangle будет отображаться Tria…. Чтобы избежать этого, мы можем объявить логическую переменную и заставить ее переключать свое значение перед withAnimation внутри нашей кнопки:

Все сделано! Вы можете запустить свой код и увидеть, как ваша фигура анимируется: