Я новичок в SwiftUI, поэтому прошу прощения, если это очень простой вопрос. В настоящее время я создаю представление, которое позволяет пользователям видеть изображения, которые они ранее добавили в приложение, в полноэкранном режиме.
У меня возникает много проблем при попытке добавить в представление функцию масштабирования ( последние 2 недели я боролся).
Мне удалось заставить работать масштабирование, но это не очень плавно, и поэтому я не могу понять, как увеличить масштаб в определенном месте, а не только по центру. Пользователи ожидают, что место, где они сжимают, будет отражать масштаб масштабирования, но у меня это не работает. Я также хочу, чтобы у пользователя была возможность перемещаться по этому увеличенному изображению, но приложению сложно отличить перетаскивание, чтобы закрыть представление, и пользователя, желающего панорамировать изображение.
В целом представление просто очень тормозит и не реагирует. и не очень хороший интерфейс. У большинства приложений есть такая возможность, поэтому я наверняка что-то упускаю, это не может быть так сложно.
Другие решения, которые я видел, имеют аналогичную проблему с моим: приложение не может одновременно перетаскивать отпустите и сведите пальцы для масштабирования/панорамирования для навигации, поскольку они не различаются.
struct FullScreenImageView: View {
let image: UIImage
@Binding var selectedImage: UIImage?
@Environment(\.presentationMode) var presentationMode
@State private var showControls = false
@State private var dragOffset = CGSize.zero
@State private var scale: CGFloat = 1.0
@State private var contentOffset = CGSize.zero // Tracks the image position when zoomed in
var body: some View {
ZStack {
// Background
Color.gray.ignoresSafeArea()
Color.black
.opacity(1 - Double(abs(dragOffset.height) / 300))
.ignoresSafeArea()
// Image
Image(uiImage: image)
.resizable()
.scaledToFit()
.ignoresSafeArea()
.offset(x: contentOffset.width + dragOffset.width, y: contentOffset.height + dragOffset.height)
.scaleEffect(scale)
.gesture(
DragGesture()
.onChanged { value in
if scale > 1.0 { // Only allow dragging when zoomed in
dragOffset = value.translation
} else {
dragOffset = CGSize(width: 0, height: value.translation.height)
}
}
.onEnded { value in
if scale > 1.0 {
// Update content offset and clamp within bounds
let newOffset = CGSize(
width: contentOffset.width + value.translation.width,
height: contentOffset.height + value.translation.height
)
contentOffset = clampOffset(newOffset, scale: scale)
dragOffset = .zero
} else {
// Handle drag-to-dismiss when not zoomed in
if abs(dragOffset.height) > 150 {
presentationMode.wrappedValue.dismiss()
} else {
withAnimation {
dragOffset = .zero
}
}
}
}
)
.gesture(
MagnificationGesture()
.onChanged { value in
scale = max(1.0, value) // Prevent scale below 1.0
}
.onEnded { _ in
withAnimation {
scale = max(1.0, scale) // Reset scale to 1.0 if too small
contentOffset = clampOffset(contentOffset, scale: scale) // Clamp offset after zooming
}
}
)
.onTapGesture {
withAnimation {
showControls.toggle()
}
}
// Control Bar
if showControls {
VStack {
HStack {
// Close Button
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark")
.font(.title2)
.padding()
}
Spacer()
// Share Button
ShareLink(item: Image(uiImage: image), preview: SharePreview("Receipt")) {
Image(systemName: "square.and.arrow.up")
.font(.title2)
}
.padding()
// Trash Button
Button(action: {
selectedImage = nil
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "trash")
.foregroundColor(.red)
.font(.title2)
.padding()
}
}
.frame(maxWidth: .infinity)
.frame(height: 45)
.background(
Color(red: 0.1, green: 0.1, blue: 0.1)
.opacity(1 - Double(abs(dragOffset.height) / 300))
)
.foregroundColor(.white)
.padding(.top, 10)
Spacer()
}
.transition(.move(edge: .top))
}
}
.statusBarHidden(true)
}
// Function to Clamp Offset to Prevent Image from Moving Out of Bounds
private func clampOffset(_ offset: CGSize, scale: CGFloat) -> CGSize {
// Calculate image dimensions based on the current scale
let imageWidth = UIScreen.main.bounds.width * scale
let imageHeight = UIScreen.main.bounds.height * scale
// Calculate horizontal and vertical bounds
let horizontalBound = (imageWidth - UIScreen.main.bounds.width) / 2
let verticalBound = (imageHeight - UIScreen.main.bounds.height) / 2
// Clamp the offset within the bounds
let clampedWidth = min(max(offset.width, -horizontalBound), horizontalBound)
let clampedHeight = min(max(offset.height, -verticalBound), verticalBound)
return CGSize(width: clampedWidth, height: clampedHeight)
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... ue-swiftui
Проблема с масштабированием ImagePreview SwiftUI ⇐ IOS
Программируем под IOS
-
Anonymous
1737752345
Anonymous
Я новичок в SwiftUI, поэтому прошу прощения, если это очень простой вопрос. В настоящее время я создаю представление, которое позволяет пользователям видеть изображения, которые они ранее добавили в приложение, в полноэкранном режиме.
У меня возникает много проблем при попытке добавить в представление функцию масштабирования ( последние 2 недели я боролся).
Мне удалось заставить работать масштабирование, но это не очень плавно, и поэтому я не могу понять, как увеличить масштаб в определенном месте, а не только по центру. Пользователи ожидают, что место, где они сжимают, будет отражать масштаб масштабирования, но у меня это не работает. Я также хочу, чтобы у пользователя была возможность перемещаться по этому увеличенному изображению, но приложению сложно отличить перетаскивание, чтобы закрыть представление, и пользователя, желающего панорамировать изображение.
В целом представление просто очень тормозит и не реагирует. и не очень хороший интерфейс. У большинства приложений есть такая возможность, поэтому я наверняка что-то упускаю, это не может быть так сложно.
Другие решения, которые я видел, имеют аналогичную проблему с моим: приложение не может одновременно перетаскивать отпустите и сведите пальцы для масштабирования/панорамирования для навигации, поскольку они не различаются.
struct FullScreenImageView: View {
let image: UIImage
@Binding var selectedImage: UIImage?
@Environment(\.presentationMode) var presentationMode
@State private var showControls = false
@State private var dragOffset = CGSize.zero
@State private var scale: CGFloat = 1.0
@State private var contentOffset = CGSize.zero // Tracks the image position when zoomed in
var body: some View {
ZStack {
// Background
Color.gray.ignoresSafeArea()
Color.black
.opacity(1 - Double(abs(dragOffset.height) / 300))
.ignoresSafeArea()
// Image
Image(uiImage: image)
.resizable()
.scaledToFit()
.ignoresSafeArea()
.offset(x: contentOffset.width + dragOffset.width, y: contentOffset.height + dragOffset.height)
.scaleEffect(scale)
.gesture(
DragGesture()
.onChanged { value in
if scale > 1.0 { // Only allow dragging when zoomed in
dragOffset = value.translation
} else {
dragOffset = CGSize(width: 0, height: value.translation.height)
}
}
.onEnded { value in
if scale > 1.0 {
// Update content offset and clamp within bounds
let newOffset = CGSize(
width: contentOffset.width + value.translation.width,
height: contentOffset.height + value.translation.height
)
contentOffset = clampOffset(newOffset, scale: scale)
dragOffset = .zero
} else {
// Handle drag-to-dismiss when not zoomed in
if abs(dragOffset.height) > 150 {
presentationMode.wrappedValue.dismiss()
} else {
withAnimation {
dragOffset = .zero
}
}
}
}
)
.gesture(
MagnificationGesture()
.onChanged { value in
scale = max(1.0, value) // Prevent scale below 1.0
}
.onEnded { _ in
withAnimation {
scale = max(1.0, scale) // Reset scale to 1.0 if too small
contentOffset = clampOffset(contentOffset, scale: scale) // Clamp offset after zooming
}
}
)
.onTapGesture {
withAnimation {
showControls.toggle()
}
}
// Control Bar
if showControls {
VStack {
HStack {
// Close Button
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark")
.font(.title2)
.padding()
}
Spacer()
// Share Button
ShareLink(item: Image(uiImage: image), preview: SharePreview("Receipt")) {
Image(systemName: "square.and.arrow.up")
.font(.title2)
}
.padding()
// Trash Button
Button(action: {
selectedImage = nil
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "trash")
.foregroundColor(.red)
.font(.title2)
.padding()
}
}
.frame(maxWidth: .infinity)
.frame(height: 45)
.background(
Color(red: 0.1, green: 0.1, blue: 0.1)
.opacity(1 - Double(abs(dragOffset.height) / 300))
)
.foregroundColor(.white)
.padding(.top, 10)
Spacer()
}
.transition(.move(edge: .top))
}
}
.statusBarHidden(true)
}
// Function to Clamp Offset to Prevent Image from Moving Out of Bounds
private func clampOffset(_ offset: CGSize, scale: CGFloat) -> CGSize {
// Calculate image dimensions based on the current scale
let imageWidth = UIScreen.main.bounds.width * scale
let imageHeight = UIScreen.main.bounds.height * scale
// Calculate horizontal and vertical bounds
let horizontalBound = (imageWidth - UIScreen.main.bounds.width) / 2
let verticalBound = (imageHeight - UIScreen.main.bounds.height) / 2
// Clamp the offset within the bounds
let clampedWidth = min(max(offset.width, -horizontalBound), horizontalBound)
let clampedHeight = min(max(offset.height, -verticalBound), verticalBound)
return CGSize(width: clampedWidth, height: clampedHeight)
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79385617/imagepreview-zoom-issue-swiftui[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия