I'm building a photo gallery using SwiftUI, and am trying to ensure that a user can smoothly scroll through thousands of photo thumbnails without performance degradation or visible load times for each photo.
So far, my research has led me to use a lazyvgrid within a ScrollView, which seems to perform better than a lazyvstack or a normal grid when working with a large data set. However, when scrolling through the lazyvgrid, it takes a moment for each new row of thumbnails to load (since lazyvgrid is lazy), and this is especially noticeable when scrolling very quickly.
Ultimately, I'm wondering how other apps with photo galleries get around this issue. Is it impossible to avoid when using SwiftUI, and would I need to use something like UIKit's CollectionView with prefetching?
Here's what I'm doing currently:
ScrollView {
LazyVGrid(columns: vGridLayout) {
ForEach(photoLibraryService.items, id: \.self) { asset in
PhotoThumbnailView(assetLocalId: asset.localIdentifier, mediaType: asset.mediaType, duration: asset.duration)
}
}
}
And here's what it looks like when I scroll through it quickly:
Related
I want to implement a vertical scroll page like system workout app.
Now I can get a similar effect with this:
TabView {
page1
.rotationEffect(.degrees(90))
page2
.rotationEffect(.degrees(90))
}.tabViewStyle(.page(indexDisplayMode: .automatic))
.rotationEffect(.degrees(-90))
But not good as system workout app does. It supports digital crown and dynamic show indicator and custom color.
So , how to implement that vertical scroll effect?
https://github.com/fredyshox/PageView
This repo works well except crown supports.
So I'm try to use ScrollViewReader to programmatically scroll a horizontal scroll view. I thought it would work like scrollToItem with .centeredHorizontally in UIKit, and for the most part it does, but the last few elements in the scroll view are being forcefully scrolled to the center of the screen, despite the fact that the scroll view isn't normally able to scroll that far over (without snapping back after releasing the drag, at least). This ends up creating white space across the trailing half of the screen.
I've seen some other questions about this and it seems like the general opinion is that it's not a bug? On the one hand I suppose we're telling the scroll view to center the item, and it's doing just that -- so, not a bug? On the other hand, that's not how similar functionality worked in UIKit. Also, this behavior is only happening on the trailing end of the scroll view! If it was the intended behavior I would expect that scrolling to the first element in the scroll view using .center anchor would force it into the center of the screen and leave leading white space, but this doesn't happen.
Is there an elegant solution to this? Or do we have to calculate the width of our elements + spacing and figure out based on the screen width whether we should anchor .center or just scroll to the last element with anchor .trailing in order to replicate the UIKit behavior?
I found a package (Amzd/ScrollViewProxy) that was made before ScrollViewReader was released that functions much the same as ScrollViewReader, but also seems to not have the bug (if it is a bug) detailed in the question.
Usage examples can be seen on the repository page, but here's a quick minimal example.
ScrollView(.horizontal) { scrollProxy in
ForEach(sections) { section in
Text(section.text)
.scrollId(section.id)
}
.onChange(of: index) {
scrollProxy.scrollTo(
sections[index].id,
alignment: .center
)
}
}
The package adds a convenience init to ScrollView to give access to the scrollProxy.
I can confirm this behavior and think it should be considered a bug. Especially since the scroll view will "jump" into position on the first touch event.
As of iOS 15.4 Beta 1 this is fixed for me. Maybe give it another try.
This question already has answers here:
How to hide the home indicator with SwiftUI?
(6 answers)
Hide the Home Indicator in Swift 2.0
(1 answer)
Closed 1 year ago.
I have a View that has some VStacks and ZStacks (top bar, carousel, detail view with if condition).
This code changes fullscreen/not fullscreen appearance:
.edgesIgnoringSafeArea(viewModel.currentItem != nil ? .all : [])
But even without .all activated I have a strange bottom Home bar appearance like there is a gradient/shadow overlay on it:
What could cause this and how to avoid this?
P.S. I also noticed in my UI hierarchy that HostingViewController is a subview of the UIDropShadowView.
P.P.S. It also doesn't go when navigation to other view with NavigationLink
That is not an issue, it should be like that, since we have no touch id in new iPhone models, that things play as kind of help in Screen. And when you use edgesIgnoringSafeArea in your code, you get access to under area and back area of that shape for Color works!
That shape is used for Swipe up to go iPhone main screens.
Look at the iPhone 8, it has touch, and look at iPhone 11, No touch ID!
When embedding a PowerBI report into a mobile app, switching the view from portrait to landscape results in an excess of grey space appearing below the report that wasn't there when the report initially loaded in portrait view. Switching back and forth between landscape and portrait does not restore the original/appropriate height inside the iframe it seems.
The report is loaded with the following configuration:
{
type: 'report',
embedUrl: 'https://app.powerbi.com/reportEmbed',
layoutType: models.LayoutType.Custom,
customLayout: {
displayOption: models.DisplayOption.FitToPage
}
...
}
I would have expected the report to maintain the amount of space in the iframe needed to display report content and not have excess grey space remain/present. This seems like something that is being handled inside reportEmbed.*.js. Any assistance would be greatly appreciated.
The scrollbar in the image gives a relative idea of how far down we are in the iframe.
UPDATE (19/07/18): This was tested on an iPhone running iOS 9.3.
FitToPage option maintains the proportions of the page, and might still have gray shoulders remaining for iframes that don't hold the same ratio for height & width.
however, recent feature allows you to make the gray shoulders disappear:
https://github.com/Microsoft/PowerBI-JavaScript/wiki/Transparent-Background
Is famo.us currently suitable for landscape oriented development ? I'm especially concerned in making it to work on iPhone. As I saw unfortunately the iOS < 7.1 safari takes a quarter of the height just for the navigation bar. Hiding it completely involves adding the app (webpage) to the main screen.
Famo.us is most certainly suitable for landscape oriented Design. The sizing feature of 'undefined' for Famo.us surfaces and the origin constraints on modifiers allow for designs to fit any number of device sizes and orientations.
Detecting an orientation change using only Famo.us can be done using something similar to the following..
Engine.on('resize',function(){
size = context.getSize();
if (size[0] > size[1]) {
// landscape
} else {
// portrait
}
});
Right now there isn't a way to automagically hide browser chrome without saving to home screen with the proper meta tags for ios and android. Alternatively, a Famo.us app can be wrapped in Cordova and distributed on AppStore and Google's Play Store, and the app will display in full screen without browser chrome.