netflix
We will develop a play pause button similar to the one the Netflix video player has.
我們將開發一個類似于Netflix視頻播放器的播放暫停按鈕。
Since Swift has replaced Objective-C as the default development language for iOS, the same will apply to SwiftUI and UIKit soon enough. Therefore we will be using SwiftUI to develop our button.
由于Swift已將Objective-C替換為iOS的默認開發語言,因此同樣很快將適用于SwiftUI和UIKit。 因此,我們將使用SwiftUI開發按鈕。
PlayButton.swift (PlayButton.swift)
Create a new Xcode project, using the iOS Single View Application template. Let’s call it PlayButtonDemo. In the next screen, make sure to select SwiftUI in the drop down menu titled User Interface.
使用iOS Single View Application模板創建一個新的Xcode項目。 我們稱之為PlayButtonDemo 。 在下一個屏幕中,確保在標題為用戶界面的下拉菜單中選擇SwiftUI 。

Create a new User Interface file, select the SwiftUI View option. Call it PlayButton.
創建一個新的用戶界面文件,選擇SwiftUI View選項。 稱之為PlayButton 。

In PlayButton.swift add an action
property to the PlayButton
struct, that takes a closure as its value. This will be the action the button performs when tapped.
在PlayButton.swift中,將action
屬性添加到PlayButton
結構中,該屬性將閉包作為其值。 這是輕按按鈕時按鈕執行的操作 。
var action: () -> Void
PlayButton_Preview
will throw a "Missing Argument…" error. Fix it by supplying the action
argument. We will set a simple action that prints Hello World!.
PlayButton_Preview
將引發“ Missing Argument…”錯誤。 通過提供action
參數對其進行修復。 我們將設置一個簡單的動作來打印Hello World! 。
struct PlayButton_Previews: PreviewProvider {
static var previews: some View {
PlayButton {
print("Hello Button")
}
}
}
At the end of PlayButton
, create a new Shape
struct, called PlayPauseShape
.
在PlayButton
的結尾,創建一個新的Shape
結構,稱為PlayPauseShape
。
The above will create a rectangular shape using the supplied rect
parameter for dimensions.Back in PlayButton
, change the default Text("Hello, World!")
to PlayPauseShape()
. Our Canvas will look like this.
上面將使用提供的rect
參數創建尺寸的rect
。 PlayButton
,將默認Text("Hello, World!")
更改為PlayPauseShape()
。 我們的畫布看起來像這樣。

We clearly don’t intend to use a button that big. Let’s set a more appropriate size for our button.
我們顯然不打算使用那么大的按鈕。 讓我們為按鈕設置一個更合適的大小。
In PlayButton_Previews
add a frame
modifier to PlayButton
.
在PlayButton_Previews
添加一個frame
修飾符PlayButton
。
PlayButton {
print("Hello World!")
}
.frame(width: 128, height: 128)

Before we start creating the shape, let’s complete PlayButton
's construction, by making the button accessible and adding a tap gesture recognizer to it.
在開始創建形狀之前,讓按鈕可訪問并向其添加輕擊手勢識別器,以完成PlayButton
的構建。
With regards to accessibility, when video is playing on device, the Pause button is what a user will see. Likewise, when video is paused, the user will see the Play button. Hence VoiceOver will report exactly what the button looks like.The .isButton
accessibility trait, informs VoiceOver that it should report this UI element as a button. And finally, when the user double taps the element while it's in focus, VoiceOver will perform performTap()
, the same function that our tap gesture recognizer calls.performTap()
toggles the button's internal state, from pause to play and vice verca, and then calls the action that is passed in when setting up the button in its parent view.The .contentShape(Rectangle)
modifier informs SwiftUI that the button's content has a rectangular shape, making the whole area tappable. Without this modifier, SwiftUI will mask the button's tappable hit area to the shape of our play/pause shape.With our type complete, let us turn our attention to the shape.
關于可訪問性,當在設備上播放視頻時,用戶將看到“ 暫停”按鈕。 同樣,當視頻暫停時,用戶將看到“ 播放”按鈕。 因此,VoiceOver將準確報告按鈕的外觀.isButton
可訪問性特征通知VoiceOver它應將此UI元素報告為按鈕。 最后,當用戶在焦點對準的位置上雙擊元素時,VoiceOver將執行performTap()
,這與我們的點擊手勢識別器調用的功能相同。 performTap()
可以將按鈕的內部狀態從暫停狀態切換為播放狀態,然后從反之亦然,然后調用在其父視圖中設置按鈕時傳遞的動作。.contentShape .contentShape(Rectangle)
修飾符通知SwiftUI該按鈕的內容包含矩形,使整個區域都可以輕敲。 如果沒有此修飾符, SwiftUI將把按鈕的可點擊擊中區域遮蓋為播放/暫停形狀的形狀。完成鍵入后,讓我們將注意力轉移到形狀上。
PlayPauseShape (PlayPauseShape)
We want to split a triangle in half, we want each half to morph into a rectangle. The first challange would be to find the point D in the image below, the intersection of the triangle's top edge with the line running across its centre.
我們想將三角形??分成兩半,我們希望每個半都變形成矩形。 第一個挑戰是在下圖中找到點D ,即三角形的上邊緣與穿過其中心的線的交點。

It’s actually quite simple, all we need to do is, find the equation of the line using two points A (0
, 0
) and B (width
, height * 0.5
).First we find the slope M,M = (By - Ay)/(Bx - Ax) => M = (height * 0.5
)/width
We know that D = (width * 0.5
, Dy)Substitue D with either A or B into the slope equation will get us the following:Dy = M(Dx - Ax) + Ay => Dy = (height * 0.5
)/width
* (width * 0.5
)With regards to E, since the play shape is an equilateral triangle (the angles inside the triangle are all the same)Ey = height
- Dy.
這其實很簡單,我們需要做的是,找到使用兩個點A(該直線的方程0
, 0
)和B( width
, height * 0.5
)。首先,我們發現斜率M,M =(B Y形 - 甲 Y)/(B X - 甲 X)=> M =( height * 0.5
)/ width
我們知道,d =( width * 0.5
,d y)的與A或B成坡方程式Substitue d將得到我們D y = M ( D x - A x )+ A y => D y =( height * 0.5
)/ width
*( width * 0.5
)關于E ,由于游戲形狀是等邊三角形 (角度三角形內部都相同) E y = height
-D y 。
We will use a Path
to draw the two halves, each half will be a subpath of the main path, and now that we have solved for all the unknowns (width
and height
are supplied to us by Shape's path(in:)
) the first subpath will have the following points (A, D, E, C) and our second subpath will have (D, B, B, E). The duplicate B is not an error, we are animating from a triangle to a rectangular shape, it's better to just collpase the point onto it's self when it's a triangle.With regards to the pause shape, we provide each subpath with a rectangle that is offset from the center of the shape.
我們將使用Path
繪制兩半,每一半將成為主路徑的子路徑,現在我們已經解決了所有未知數(Shape的path(in:)
提供了width
和height
),第一個子路徑將具有以下點( A , D , E , C ),而我們的第二個子路徑將具有( D , B , B , E )。 重復的B并不是錯誤,我們正在從三角形到矩形進行動畫制作,最好是將點變成三角形時將其自身折疊起來。關于暫停形狀,我們為每個子路徑提供一個矩形從形狀中心偏移。

In UIKit, animating between two paths is very easy using CABasicAnimation
. In SwiftUI in not as straight forward. We need to provide a parameter to SwiftUI for interpolation. So if we wanted to animate from 0 to 1, SwiftUI will provide us with (0.0, 0.1, 0.2 ... 1.0). We inform SwiftUI of the parameter by implementing the animateableData
property on types that conform to Animateable
. Hence that parameter needs to be part of the path for the animation to take effect.
在UIKit中 ,使用CABasicAnimation
非常容易在兩條路徑之間進行動畫處理。 在SwiftUI中并不是那么簡單。 我們需要為SwiftUI提供參數進行插值。 因此,如果我們想從0到1進行動畫處理,SwiftUI將為我們提供(0.0,0.1,0.2 ... 1.0)。 我們通過在符合Animateable
類型上實現animateableData
屬性來告知SwiftUI參數。 因此,該參數必須是動畫生效路徑的一部分。
For a great write on SwiftUI animation, checkout out this post.
要獲得有關SwiftUI動畫的出色文章,請查看這篇文章 。
We’ll go through how to animate from the play shape’s A point to pause shape’s A point. We define the two points leftPlayTopLeft
and leftPauseTopLeft
. We find out how far the point has to move from pause's top left to play's top left. Mutliplying the result by the interpolation value and adding to leftPauseTopLeft
will animate between to the two shapes.
我們將介紹如何從游戲形狀的A點進行動畫,以暫停形狀的A點。 我們定義了兩點leftPlayTopLeft
和leftPauseTopLeft
。 我們發現該點必須從暫停的左上角移動到游戲的左上角。 將結果與插值值leftPauseTopLeft
并添加到leftPauseTopLeft
將在這兩個形狀之間進行動畫處理。
Back to PlayButton.swift, we will now define all 8 points as described above in a function called pathPoints. The value that is being interpolated her is the shift
property.
返回PlayButton.swift ,我們現在將在上述名為pathPoints的函數中定義所有8個點。 她要插值的值是shift
屬性。
pathPoints(width:height)
returns an array that's holding two arrays. The first array contains all the points for the left subpath, while the second array provides the points for the right subpath.We update path(in:)
function to loop through the arrays and draw the lines.
pathPoints(width:height)
返回一個包含兩個數組的數組。 第一個數組包含左子路徑的所有點,第二個數組提供右子路徑的點。我們更新path(in:)
函數以遍歷數組并繪制線。
Click the Live Preview button in the canvas and tap away, you should get the button behaving as below.
單擊畫布中的“ 實時預覽”按鈕,然后輕按一下,您將獲得如下所示的按鈕。

As always you can download the completed project from github.com.
與往常一樣,您可以從github.com下載完成的項目。
Thank you for reading.
感謝您的閱讀。
翻譯自: https://uxdesign.cc/anatomy-of-the-netflix-play-button-d45cf0eb18c6
netflix
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。 如若轉載,請注明出處:http://www.pswp.cn/news/274762.shtml 繁體地址,請注明出處:http://hk.pswp.cn/news/274762.shtml 英文地址,請注明出處:http://en.pswp.cn/news/274762.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!