Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
P
PhoneManager
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Yang
PhoneManager
Commits
7a44f2d6
Commit
7a44f2d6
authored
May 12, 2025
by
CZ1004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【新增】左右滑动UI
parent
3048c9af
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
312 additions
and
0 deletions
+312
-0
PhotoSlideViewController.swift
...ss/Session/Home/Controller/PhotoSlideViewController.swift
+263
-0
AnchorRotatableView.swift
...Manager/Class/Session/Home/View/AnchorRotatableView.swift
+49
-0
No files found.
PhoneManager/Class/Session/Home/Controller/PhotoSlideViewController.swift
0 → 100644
View file @
7a44f2d6
//
// PhotoSlideViewController.swift
// AIClean
//
// Created by 赵前 on 2025/5/10.
//
import
UIKit
class
PhotoSlideViewController
:
BaseViewController
{
// 按钮竖直方向偏移量
let
buttonVerticalOffset
:
CGFloat
=
20
// MARK: - 数据与视图
var
dataSource
:
[
AssetModel
]
=
[]
private
var
currentIndex
=
0
private
var
nextIndex
=
0
private
lazy
var
topView
:
AnchorRotatableView
=
{
let
view
=
AnchorRotatableView
()
view
.
configure
(
anchorPoint
:
CGPoint
(
x
:
0.5
,
y
:
0.5
))
return
view
}()
private
lazy
var
bottomView
:
AnchorRotatableView
=
{
let
view
=
AnchorRotatableView
()
view
.
configure
(
anchorPoint
:
CGPoint
(
x
:
0.5
,
y
:
0.5
))
return
view
}()
private
let
leftButton
:
UIButton
=
{
let
btn
=
UIButton
()
btn
.
setTitle
(
"Left"
,
for
:
.
normal
)
btn
.
backgroundColor
=
.
systemBlue
.
withAlphaComponent
(
0.8
)
btn
.
alpha
=
0
btn
.
layer
.
cornerRadius
=
8
return
btn
}()
private
let
rightButton
:
UIButton
=
{
let
btn
=
UIButton
()
btn
.
setTitle
(
"Right"
,
for
:
.
normal
)
btn
.
backgroundColor
=
.
systemBlue
.
withAlphaComponent
(
0.8
)
btn
.
alpha
=
0
btn
.
layer
.
cornerRadius
=
8
return
btn
}()
// MARK: - 生命周期
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
setupData
()
setupViews
()
setupGestures
()
}
// MARK: - 初始化方法
private
func
setupData
()
{
currentIndex
=
dataSource
.
count
-
1
updateCardContent
()
}
private
func
setupViews
()
{
// 卡片视图
view
.
addSubview
(
bottomView
)
view
.
addSubview
(
topView
)
topView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
100
)
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
100
)
make
.
left
.
equalToSuperview
()
.
offset
(
20
)
make
.
right
.
equalToSuperview
()
.
offset
(
-
20
)
}
bottomView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
100
)
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
100
)
make
.
left
.
equalToSuperview
()
.
offset
(
20
)
make
.
right
.
equalToSuperview
()
.
offset
(
-
20
)
}
// 操作按钮
view
.
addSubview
(
leftButton
)
view
.
addSubview
(
rightButton
)
resetButtonsPosition
()
}
private
func
resetButtonsPosition
()
{
leftButton
.
snp
.
makeConstraints
{
make
in
make
.
height
.
width
.
equalTo
(
50
)
make
.
centerX
.
equalTo
(
100
)
make
.
centerY
.
equalTo
(
100
)
}
rightButton
.
snp
.
makeConstraints
{
make
in
make
.
height
.
width
.
equalTo
(
50
)
make
.
centerX
.
equalTo
(
45
)
make
.
centerY
.
equalTo
(
100
)
}
}
private
func
setupGestures
()
{
let
pan
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
handlePan(_:)
)
)
topView
.
addGestureRecognizer
(
pan
)
}
// MARK: - 手势处理
@objc
private
func
handlePan
(
_
gesture
:
UIPanGestureRecognizer
)
{
let
translation
=
gesture
.
translation
(
in
:
view
)
let
velocity
=
gesture
.
velocity
(
in
:
view
)
switch
gesture
.
state
{
case
.
began
:
break
case
.
changed
:
let
progress
=
translation
.
x
*
2
/
topView
.
bounds
.
size
.
width
updateCardTransform
(
translation
:
translation
)
updateButtons
(
progress
:
progress
,
translation
:
translation
)
case
.
ended
,
.
cancelled
:
endDragAnimation
(
velocity
:
velocity
)
default
:
break
}
}
// MARK: - 新手势绑定
private
func
setupGesturesForNewTopView
()
{
// 移除旧手势
topView
.
gestureRecognizers
?
.
forEach
{
topView
.
removeGestureRecognizer
(
$0
)
}
// 添加新手势
let
pan
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
handlePan(_:)
)
)
pan
.
delegate
=
self
topView
.
addGestureRecognizer
(
pan
)
// 确保视图层级
view
.
bringSubviewToFront
(
bottomView
)
view
.
bringSubviewToFront
(
topView
)
view
.
bringSubviewToFront
(
leftButton
)
view
.
bringSubviewToFront
(
rightButton
)
}
private
func
updateCardTransform
(
translation
:
CGPoint
)
{
let
progress
=
translation
.
x
/
topView
.
bounds
.
size
.
width
// 角度
let
rotationAngle
=
topView
.
maxRotationAngle
*
progress
topView
.
transform
=
CGAffineTransform
(
translationX
:
translation
.
x
,
y
:
0
)
.
rotated
(
by
:
rotationAngle
)
}
private
func
updateButtons
(
progress
:
CGFloat
,
translation
:
CGPoint
)
{
// 计算X轴坐标 向右的时候progress为正数
if
progress
>
0
{
leftButton
.
isHidden
=
false
rightButton
.
isHidden
=
true
}
else
{
leftButton
.
isHidden
=
true
rightButton
.
isHidden
=
false
}
let
leftX
=
min
(
translation
.
x
+
25
,
topView
.
bounds
.
size
.
width
/
2
)
let
rightX
=
max
(
360
-
abs
(
translation
.
x
)
,
topView
.
bounds
.
size
.
width
/
2
)
// 计算Y轴坐标
let
verY
=
min
(
100
+
buttonVerticalOffset
,
100
+
buttonVerticalOffset
*
abs
(
progress
))
UIView
.
animate
(
withDuration
:
0.1
)
{
self
.
leftButton
.
center
=
CGPoint
(
x
:
leftX
,
y
:
verY
)
self
.
rightButton
.
center
=
CGPoint
(
x
:
rightX
,
y
:
verY
)
// 渐变效果
let
alpha
=
abs
(
progress
)
self
.
leftButton
.
alpha
=
alpha
self
.
rightButton
.
alpha
=
alpha
}
}
private
func
endDragAnimation
(
velocity
:
CGPoint
)
{
let
translation
=
topView
.
transform
.
tx
let
shouldDisappear
=
abs
(
translation
)
>
topView
.
bounds
.
size
.
width
/
2
||
abs
(
velocity
.
x
)
>
800
self
.
leftButton
.
alpha
=
0
self
.
rightButton
.
alpha
=
0
shouldDisappear
?
animateCardDisappear
()
:
resetCardPosition
()
}
private
func
animateCardDisappear
()
{
let
direction
:
UISwipeGestureRecognizer
.
Direction
=
topView
.
transform
.
tx
>
0
?
.
right
:
.
left
UIView
.
animate
(
withDuration
:
0.4
)
{
let
targetX
=
direction
==
.
right
?
self
.
view
.
bounds
.
width
*
1.5
:
-
self
.
view
.
bounds
.
width
*
1.5
self
.
topView
.
transform
=
CGAffineTransform
(
translationX
:
targetX
,
y
:
0
)
self
.
topView
.
alpha
=
0
}
completion
:
{
_
in
self
.
handleCardDisappeared
()
}
}
private
func
resetCardPosition
()
{
UIView
.
animate
(
withDuration
:
0.6
,
delay
:
0
,
usingSpringWithDamping
:
0.6
,
initialSpringVelocity
:
0.5
)
{
self
.
topView
.
transform
=
.
identity
self
.
resetButtonsPosition
()
}
}
// MARK: - 数据更新
private
func
updateCardContent
()
{
guard
dataSource
.
indices
.
contains
(
currentIndex
)
else
{
return
}
// 获取资源
topView
.
imageView
.
image
=
PhotoAndVideoMananger
.
mananger
.
getImageFromAssetID
(
id
:
dataSource
[
currentIndex
]
.
localIdentifier
)
// 预加载下一张
let
next
=
currentIndex
-
1
>=
0
?
currentIndex
-
1
:
dataSource
.
count
-
1
bottomView
.
imageView
.
image
=
PhotoAndVideoMananger
.
mananger
.
getImageFromAssetID
(
id
:
dataSource
[
next
]
.
localIdentifier
)
}
private
func
handleCardDisappeared
()
{
// 更新索引(循环逻辑)
currentIndex
=
currentIndex
-
1
>=
0
?
currentIndex
-
1
:
dataSource
.
count
-
1
// 交换视图层级
let
temp
=
topView
topView
=
bottomView
bottomView
=
temp
// 重置视图状态
topView
.
transform
=
.
identity
topView
.
alpha
=
1
topView
.
isUserInteractionEnabled
=
true
// 重新绑定新手势
setupGesturesForNewTopView
()
resetButtonsPosition
()
updateCardContent
()
// 重置底层视图位置
bottomView
.
snp
.
remakeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
100
)
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
100
)
make
.
left
.
equalToSuperview
()
.
offset
(
20
)
make
.
right
.
equalToSuperview
()
.
offset
(
-
20
)
}
bottomView
.
transform
=
.
identity
bottomView
.
alpha
=
1
}
}
extension
PhotoSlideViewController
:
UIGestureRecognizerDelegate
{
func
gestureRecognizer
(
_
gestureRecognizer
:
UIGestureRecognizer
,
shouldRecognizeSimultaneouslyWith
otherGestureRecognizer
:
UIGestureRecognizer
)
->
Bool
{
return
true
}
}
PhoneManager/Class/Session/Home/View/AnchorRotatableView.swift
0 → 100644
View file @
7a44f2d6
//
// AnchorRotatableView.swift
// AIClean
//
// Created by 赵前 on 2025/5/10.
//
import
Foundation
import
UIKit
class
AnchorRotatableView
:
UIView
{
var
maxRotationAngle
:
CGFloat
=
.
pi
/
12
lazy
var
imageView
:
UIImageView
=
{
let
iv
=
UIImageView
()
iv
.
contentMode
=
.
scaleAspectFill
iv
.
clipsToBounds
=
true
return
iv
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setupView
()
}
required
init
?(
coder
:
NSCoder
)
{
super
.
init
(
coder
:
coder
)
setupView
()
}
private
func
setupView
()
{
backgroundColor
=
.
gray
layer
.
cornerRadius
=
12
clipsToBounds
=
true
addSubview
(
imageView
)
imageView
.
snp
.
makeConstraints
{
$0
.
edges
.
equalToSuperview
()
}
}
}
extension
AnchorRotatableView
{
func
configure
(
anchorPoint
:
CGPoint
)
{
layer
.
anchorPoint
=
anchorPoint
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment