ux: fix image indicators
Changelog-Fixed: Fix image indicators to limit number of dots to not spill screen beyond visible margins Closes: https://github.com/damus-io/damus/issues/1227 Closes: https://github.com/damus-io/damus/issues/1295 Signed-off-by: ericholguin <ericholguin@apache.org> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
517f3714e8
commit
846a786fd0
@@ -31,6 +31,49 @@ struct ShareSheet: UIViewControllerRepresentable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom UIPageControl
|
||||||
|
struct PageControlView: UIViewRepresentable {
|
||||||
|
@Binding var currentPage: Int
|
||||||
|
var numberOfPages: Int
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeUIView(context: Context) -> UIPageControl {
|
||||||
|
let uiView = UIPageControl()
|
||||||
|
uiView.backgroundStyle = .minimal
|
||||||
|
uiView.currentPageIndicatorTintColor = UIColor(Color("DamusPurple"))
|
||||||
|
uiView.pageIndicatorTintColor = UIColor(Color("DamusLightGrey"))
|
||||||
|
uiView.currentPage = currentPage
|
||||||
|
uiView.numberOfPages = numberOfPages
|
||||||
|
uiView.addTarget(context.coordinator, action: #selector(Coordinator.valueChanged), for: .valueChanged)
|
||||||
|
return uiView
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIView(_ uiView: UIPageControl, context: Context) {
|
||||||
|
uiView.currentPage = currentPage
|
||||||
|
uiView.numberOfPages = numberOfPages
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PageControlView {
|
||||||
|
final class Coordinator: NSObject {
|
||||||
|
var parent: PageControlView
|
||||||
|
|
||||||
|
init(_ parent: PageControlView) {
|
||||||
|
self.parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func valueChanged(sender: UIPageControl) {
|
||||||
|
let currentPage = sender.currentPage
|
||||||
|
withAnimation {
|
||||||
|
parent.currentPage = currentPage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum ImageShape {
|
enum ImageShape {
|
||||||
case square
|
case square
|
||||||
@@ -227,7 +270,6 @@ struct ImageCarousel<Content: View>: View {
|
|||||||
.onChange(of: model.selectedIndex) { value in
|
.onChange(of: model.selectedIndex) { value in
|
||||||
model.selectedIndex = value
|
model.selectedIndex = value
|
||||||
}
|
}
|
||||||
.tabViewStyle(PageTabViewStyle())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -235,31 +277,11 @@ struct ImageCarousel<Content: View>: View {
|
|||||||
Medias
|
Medias
|
||||||
.onTapGesture { }
|
.onTapGesture { }
|
||||||
|
|
||||||
// This is our custom carousel image indicator
|
if urls.count > 1 {
|
||||||
CarouselDotsView(urls: urls, selectedIndex: $model.selectedIndex)
|
PageControlView(currentPage: $model.selectedIndex, numberOfPages: urls.count)
|
||||||
}
|
.frame(maxWidth: 0, maxHeight: 0)
|
||||||
}
|
.padding(.top, 5)
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Custom Carousel
|
|
||||||
struct CarouselDotsView<T>: View {
|
|
||||||
let urls: [T]
|
|
||||||
@Binding var selectedIndex: Int
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
if urls.count > 1 {
|
|
||||||
HStack {
|
|
||||||
ForEach(urls.indices, id: \.self) { index in
|
|
||||||
Circle()
|
|
||||||
.fill(index == selectedIndex ? Color("DamusPurple") : Color("DamusLightGrey"))
|
|
||||||
.frame(width: 10, height: 10)
|
|
||||||
.onTapGesture {
|
|
||||||
selectedIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.padding(.top, CGFloat(8))
|
|
||||||
.id(UUID())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,21 +37,6 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
self.content = nil
|
self.content = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabViewIndicator: some View {
|
|
||||||
HStack(spacing: 10) {
|
|
||||||
ForEach(urls.indices, id: \.self) { index in
|
|
||||||
Capsule()
|
|
||||||
.fill(index == selectedIndex ? Color.white : Color.damusMediumGrey)
|
|
||||||
.frame(width: 7, height: 7)
|
|
||||||
.onTapGesture {
|
|
||||||
selectedIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
.clipShape(Capsule())
|
|
||||||
}
|
|
||||||
|
|
||||||
var background: some ShapeStyle {
|
var background: some ShapeStyle {
|
||||||
if case .video = urls[safe: selectedIndex] {
|
if case .video = urls[safe: selectedIndex] {
|
||||||
return AnyShapeStyle(Color.black)
|
return AnyShapeStyle(Color.black)
|
||||||
@@ -115,8 +100,10 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
if (urls.count > 1) {
|
if urls.count > 1 {
|
||||||
tabViewIndicator
|
PageControlView(currentPage: $selectedIndex, numberOfPages: urls.count)
|
||||||
|
.frame(maxWidth: 0, maxHeight: 0)
|
||||||
|
.padding(.top, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.content?()
|
self.content?()
|
||||||
|
|||||||
Reference in New Issue
Block a user