I learned that the background appears on the header of the last section. Why does that happen.
Here is my code:
This situration does not occur unless .font is applied to the Text.
How can we interpret this issue?
Post
Replies
Boosts
Views
Activity
I want to create a list in the Reminders app using EventKit. For each created list, I want to create EKReminders. However, it seems that EventKit does not provide a way to create a reminder list directly. How can I achieve this?
I encountered a problem while using ScrollView in SwiftUI. When I perform a refresh, the app crashes. I access the array using an index in a ForEach loop. This is done to create new data from the array in a commonly used view. The function to create data is adopted from a protocol in the view model. I access it by index because the type of the array is not specified; each view using it may have a different data type. Below is an example code. Is it possible to access data from the array using an index? Every time I refresh, I get an "index out of range" error.
import SwiftUI
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
ScrollView {
if !viewModel.testValues.isEmpty {
LazyVStack(spacing: 20) {
ForEach(Array(zip(viewModel.testValues.indices, viewModel.testValues)), id:\.1) { index, data in
test(index: index, data: data, viewModel: viewModel)
.onAppear {
if !viewModel.isLoading, viewModel.testValues.count - 2 == index {
viewModel.fetch()
}
}
}
}
} else {
Text("tesetsetsetsettse")
}
}
.onAppear {
viewModel.fetch()
}
.refreshable {
viewModel.refresh()
}
}
}
struct test: View {
let index: Int
let data: String
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack(spacing: 8) {
test1(index: index, data: data, viewModel: viewModel)
Text("------------------------")
}
}
}
struct test1: View {
let index: Int
let data: String
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
Text(viewModel.testValues[index])
.font(.system(size: 12))
.foregroundStyle(Color.red)
.padding(.horizontal, 40)
.padding(.vertical, 50)
.background {
RoundedRectangle(cornerRadius: 20)
.fill(Color.blue)
}
}
}
}
class ViewModel: ObservableObject {
@Published var isLoading = false
@Published var testValues: [String] = []
func fetch() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.testValues += [
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
UUID().uuidString,
]
}
}
func refresh() {
testValues = []
fetch()
}
}
I’m using PDFPageOverlayViewProvider with pdfview. I want to control the visibility of the overlay view using a button. However, the view updates only when it disappears and reappears. I would like the changes to be reflected immediately. How can I achieve this?
struct PDFKitView: View {
let bookId: UUID
let bookTitle: String
@State private var currentPage = "1"
@State private var isSideTab = false
@State private var selectedNote: [SelectedNote] = []
var body: some View {
let pdfDocument = openPDF(at: bookId.uuidString)
ZStack(alignment: .trailing) {
HStack(spacing: 0) {
PDFKitRepresentableView(
bookId: bookId,
selectedNote: $selectedNote,
currentPage: $currentPage,
pdfDocument: pdfDocument
)
if isSideTab {
SideView()
.transition(.move(edge: .trailing))
.zIndex(1)
.frame(maxWidth: 260)
}
}
.padding(.top, 73)
}
.onAppear {
getAllNote(bookId: bookId)
}
.customNavigationBar(back: true) {
Text("\(currentPage)/\(pdfDocument.pageCount)")
.pretendard(.CaptionRegular)
.foregroundStyle(Color.Text.primary)
} TrailingView: {
Button(action: {
withAnimation {
isSideTab.toggle()
}
}) {
Image(systemName: SFSymbol.squareStack3dDownForwardFill.icon)
.sfPro(.IconMedium)
.foregroundStyle(Color.Text.primary)
}
}
}
@ViewBuilder
func SideView() -> some View {
VStack(spacing: 16) {
HStack(spacing: 4) {
Image(systemName: SFSymbol.squareStack3dDownForwardFill.icon)
.sfPro(.IconSmall)
.foregroundStyle(Color.Text.primary)
Text(Literals.sideTabTitle)
.pretendard(.P2Bold)
.foregroundStyle(Color.Text.primary)
Spacer()
}
.padding(16)
.background {
Color.Background.white
}
ScrollView {
ForEach($selectedNote, id: \.noteId) { note in
NoteCellView(note: note)
}
}
.background {
Color.Fill.white
}
}
.background {
Color.Background.blueGray
}
}
@ViewBuilder
func NoteCellView(note: Binding<SelectedNote>) -> some View {
HStack(alignment: .top, spacing: 16) {
Image(.writingNote)
.resizable()
.scaledToFit()
.frame(width: 42, height: 60)
VStack(alignment: .leading, spacing: 8) {
Text(note.wrappedValue.noteId == bookId.uuidString ? "345" : "123")
.foregroundStyle(Color.Text.secondary)
.padding(.horizontal, 8)
.background {
Rectangle()
.strokeBorder(Color.Layout.secondary)
}
Text(bookTitle)
.lineLimit(2)
Toggle("", isOn: note.selected)
.labelsHidden()
.tint(Color.Fill.activePrimary)
}
}
.padding(EdgeInsets(top: 20, leading: 16, bottom: 16, trailing: 16))
}
}
struct PDFKitRepresentableView: UIViewRepresentable {
let bookId: UUID
@Binding var selectedNote: [SelectedNote]
@Binding var currentPage: String
let pdfDocument: PDFDocument
let pdfView = PDFView()
let toolPicker = PKToolPicker()
func makeUIView(context: Context) -> PDFView {
pdfView.displayMode = .singlePageContinuous
pdfView.usePageViewController(false)
pdfView.displayDirection = .vertical
pdfView.pageOverlayViewProvider = context.coordinator
pdfView.autoScales = true
pdfDocument.delegate = context.coordinator
pdfView.document = pdfDocument
return pdfView
}
func updateUIView(_ uiView: PDFView, context: Context) {
if
let localNote = selectedNote.first(where: {$0.noteId == bookId.uuidString}),
!localNote.selected
{
toolPicker.setVisible(false, forFirstResponder: uiView)
} else {
toolPicker.setVisible(true, forFirstResponder: uiView)
}
uiView.becomeFirstResponder()
}
func makeCoordinator() -> CanvasProvider {
return CanvasProvider(parent: self)
}
}
final class CanvasProvider: NSObject, PDFPageOverlayViewProvider, PDFDocumentDelegate {
var localNotes = [PDFPage: PKCanvasView]()
var passNotes = [PDFPage: Image]()
let parent: PDFKitRepresentableView
init(parent: PDFKitRepresentableView) {
self.parent = parent
super.init()
getDrawingDatas(
bookId: parent.bookId.uuidString,
selectedNote: parent.selectedNote,
document: parent.pdfDocument
)
}
func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {
var coverView: PKCanvasView? = PKCanvasView()
if
let view = localNotes[page],
parent.selectedNote.first(where: { $0.noteId == parent.bookId.uuidString })?.selected ?? false
{
view.backgroundColor = .clear
view.isOpaque = true
view.drawingPolicy = .anyInput
view.delegate = self
parent.toolPicker.addObserver(view)
coverView = view
(page as? CanvasPDFPage)?.canvasView = view
} else {
coverView = nil
}
for subView in view.documentView?.subviews ?? [] {
if subView.theClassName == "PDFPageView" {
subView.isUserInteractionEnabled = true
}
}
return coverView
}
func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) { }
func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for page: PDFPage) { }
}
I need to apply security measures to a PDF. My goal is to prevent it from being leaked, and even if it is leaked, I want to ensure that the PDF cannot be viewed. Is it possible to use pdfkit and apply DRM to achieve this?⬤
I want to add a pkcanvasview image and change its position and size by dragging. And I want to draw a picture using a pencil on top.
The image must be able to change its position at any time, and a picture must be added on top.
If I add it to the subview of pkcanvasview, I cannot do what I want. How can I do this?
I am using PDFPageOverlayViewProvider from pdfkit. I would like to detect changes in the overlaid view and refresh PDFPageOverlayViewProvider. Currently, it does not refresh even when the overlaid view changes. Is there a way to refresh it?