### Example of startLoading usage Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Usage pattern for starting and stopping the loading indicator during an asynchronous image load. ```swift cell.isLoadingIndicatorEnabled = true cell.startLoading() imageLoader.loadImage(for: index) { image in cell.imageView.image = image cell.stopLoading() } ``` -------------------------------- ### setup(with:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Configures initial constraints for the overlay within the photo browser. ```APIDOC ## setup(with:) ### Description Sets up initial constraints, saves a weak reference to the browser, and applies position and visibility logic. ### Signature `open func setup(with browser: JXPhotoBrowserViewController)` ### Parameters - **browser** (JXPhotoBrowserViewController) - The photo browser instance to attach to. ``` -------------------------------- ### Overlay Examples Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Add official examples for various overlays, such as close buttons, title/description overlays, download/share action bars, and top toolbars, to serve as templates for further customization. ```swift // Example overlay implementations: // CloseButtonOverlay // TitleDescriptionOverlay // DownloadShareOverlay // TopToolbarOverlay ``` -------------------------------- ### Define setup(with:) Method Signature Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md The method signature for initializing the overlay component. ```swift func setup(with browser: JXPhotoBrowserViewController) ``` -------------------------------- ### VideoPlayerCell Extension Example Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md A complete example demonstrating how to extend an image cell into a video playback cell. ```swift // Demo-UIKit/Demo/HomePage/VideoPlayerCell.swift ``` -------------------------------- ### Start loading animation Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Starts the loading indicator animation. ```swift public func startLoading() ``` -------------------------------- ### Initialize JXPhotoBrowserViewController Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXZoomImageCell.md Basic setup for the photo browser using the built-in cell. ```swift let browser = JXPhotoBrowserViewController() browser.initialIndex = 0 browser.delegate = MyDelegate() // 内置 Cell,无需手动注册 // browser.dequeueReusableCell 会返回 JXZoomImageCell browser.present(from: self) ``` -------------------------------- ### Initialize and present JXPhotoBrowser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/INDEX.md A complete example showing how to instantiate the browser, set the delegate, and present it from a view controller. ```swift // 完整示例,可直接复制使用 let browser = JXPhotoBrowserViewController() browser.delegate = delegate browser.present(from: self) ``` -------------------------------- ### PhotoBannerView Reuse Example Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md An example showcasing the reuse of the browser kernel to implement a banner view. ```swift // Demo-UIKit/Demo/HomePage/PhotoBannerView.swift ``` -------------------------------- ### setup(with:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md Initializes the overlay component when it is added to the browser view. This method is used to set up layout constraints, initial frames, and store a reference to the browser instance. ```APIDOC ## func setup(with browser: JXPhotoBrowserViewController) ### Description Called when the component is added to the browser view. Use this to perform initial layout, set up constraints, or initialize subviews. ### Parameters - **browser** (JXPhotoBrowserViewController) - The host browser instance. ``` -------------------------------- ### JXPageIndicatorOverlay Example Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md An example of an officially built-in overlay, serving as a template for other custom additional components. ```swift // Sources/JXPageIndicatorOverlay.swift ``` -------------------------------- ### Implement transitionImageView property Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserCellProtocol.md Example of providing an image view for zoom transition animations. ```swift var transitionImageView: UIImageView? { get } ``` ```swift class JXZoomImageCell: UICollectionViewCell, JXPhotoBrowserCellProtocol { let imageView: UIImageView = UIImageView() var transitionImageView: UIImageView? { imageView } ``` -------------------------------- ### Manage loading state Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Example of toggling the loading indicator state. ```swift cell.isLoadingIndicatorEnabled = true cell.startLoading() // 异步加载图片... cell.stopLoading() ``` -------------------------------- ### Auto-play banner configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Setup for banner-style auto-playing content with a page indicator. ```swift browser.transitionType = .none browser.scrollDirection = .horizontal browser.isLoopingEnabled = true browser.isAutoPlayEnabled = true browser.autoPlayInterval = 3.0 browser.addOverlay(JXPageIndicatorOverlay()) ``` -------------------------------- ### Basic Usage Example Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Standard implementation of the page indicator within a photo browser instance. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = delegate browser.addOverlay(JXPageIndicatorOverlay()) browser.present(from: self) ``` -------------------------------- ### Implement JXPhotoBrowserOverlay Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md A complete implementation example of a custom overlay view conforming to the protocol. ```swift class MyOverlay: UIView, JXPhotoBrowserOverlay { weak var browser: JXPhotoBrowserViewController? func setup(with browser: JXPhotoBrowserViewController) { self.browser = browser // 添加约束 translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ centerXAnchor.constraint(equalTo: browser.view.centerXAnchor), bottomAnchor.constraint(equalTo: browser.view.bottomAnchor, constant: -20), widthAnchor.constraint(equalToConstant: 100), heightAnchor.constraint(equalToConstant: 50) ]) } func reloadData(numberOfItems: Int, pageIndex: Int) {} func didChangedPageIndex(_ index: Int) {} } ``` -------------------------------- ### SwiftUI Bridging Entry Point Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md An example of the entry point for bridging JXPhotoBrowser into a SwiftUI project using a presenter. ```swift // Demo-SwiftUI/Demo/PhotoBrowserPresenter.swift ``` -------------------------------- ### Set image in imageView Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Examples for setting an image directly or using a loading library. ```swift cell.imageView.image = photo // 或使用图片加载库 cell.imageView.kf.setImage(with: url) ``` -------------------------------- ### Demo Project Roles Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Demo projects showcase main capabilities (UIKit), SwiftUI bridging (SwiftUI), and distribution compatibility (Carthage). Specific components like VideoPlayerCell and PhotoBannerView also serve as extension examples. ```text Demo-UIKit: Core features, mixed media, list transitions. Demo-SwiftUI: SwiftUI bridging. Demo-Carthage: Distribution compatibility. VideoPlayerCell & PhotoBannerView: Extension examples. ``` -------------------------------- ### Mixed video and image configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Setup for browsers containing both video and image content. ```swift browser.transitionType = .fade browser.scrollDirection = .horizontal browser.register(VideoPlayerCell.self, forReuseIdentifier: "video") ``` -------------------------------- ### Advanced JXPhotoBrowser Configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Comprehensive setup including auto-play, overlays, and custom cell registration. ```swift let browser = JXPhotoBrowserViewController() // 数据源 browser.delegate = MyPhotoBrowserDelegate() // 初始位置 browser.initialIndex = 2 // 滚动和分页 browser.scrollDirection = .horizontal browser.isLoopingEnabled = true browser.itemSpacing = 8 // 转场动画 browser.transitionType = .zoom // 自动轮播 browser.isAutoPlayEnabled = true browser.autoPlayInterval = 3.0 // Overlay 组件 let pageIndicator = JXPageIndicatorOverlay() pageIndicator.position = .bottom(padding: 16) pageIndicator.pageControl.currentPageIndicatorTintColor = .white browser.addOverlay(pageIndicator) // 自定义 Cell browser.register(VideoPlayerCell.self, forReuseIdentifier: "video") // 展示 browser.present(from: self) ``` -------------------------------- ### Customize loadingIndicator Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Example of customizing the appearance of the loading indicator. ```swift cell.loadingIndicator.style = .large cell.loadingIndicator.color = .white ``` -------------------------------- ### Constraint Implementation Examples Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Demonstrates the AutoLayout constraint logic used for positioning the indicator at the bottom or top of the container. ```swift // .bottom(padding: 12) 时 let centerX = centerXAnchor.constraint(equalTo: container.centerXAnchor) let bottom = bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -12) // .top(padding: 20) 时 let centerX = centerXAnchor.constraint(equalTo: container.centerXAnchor) let top = topAnchor.constraint(equalTo: container.topAnchor, constant: 20) ``` -------------------------------- ### Implement browser property Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserCellProtocol.md Example of implementing the weak browser reference to allow interaction with the browser controller. ```swift var browser: JXPhotoBrowserViewController? { get set } ``` ```swift class MyPhotoCell: UICollectionViewCell, JXPhotoBrowserCellProtocol { weak var browser: JXPhotoBrowserViewController? @IBAction func closeButtonTapped(_ sender: UIButton) { browser?.dismissSelf() } } ``` -------------------------------- ### Minimal JXPhotoBrowser Implementation Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Basic setup requiring a delegate to provide the number of items and cell configuration. ```swift import JXPhotoBrowser class PhotoBrowserDelegate: NSObject, JXPhotoBrowserDelegate { let photos: [UIImage] = [...] func numberOfItems(in browser: JXPhotoBrowserViewController) -> Int { return photos.count } func photoBrowser( _ browser: JXPhotoBrowserViewController, cellForItemAt index: Int, at indexPath: IndexPath ) -> JXPhotoBrowserAnyCell { let cell = browser.dequeueReusableCell( withReuseIdentifier: JXZoomImageCell.reuseIdentifier, for: indexPath ) as! JXZoomImageCell cell.imageView.image = photos[index] return cell } } // 使用 let browser = JXPhotoBrowserViewController() browser.delegate = PhotoBrowserDelegate() browser.present(from: self) ``` -------------------------------- ### Vertical image browsing configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Setup for vertical scrolling image galleries. ```swift browser.transitionType = .fade browser.scrollDirection = .vertical browser.isLoopingEnabled = false ``` -------------------------------- ### Configure Position Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Examples of setting the indicator position using the Position enum. ```swift let indicator = JXPageIndicatorOverlay() indicator.position = .bottom(padding: 20) indicator.position = .top(padding: 10) indicator.position = .default ``` -------------------------------- ### Implement didChangedPageIndex(_:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md Example implementation for updating UI elements when the user navigates to a new page. ```swift func didChangedPageIndex(_ index: Int) { pageControl.currentPage = index titleLabel.text = titles[index] // 更新标题 } ``` -------------------------------- ### Create Custom Overlay Component Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Implement the JXPhotoBrowserOverlay protocol to create your own overlay components. The setup method is called when the overlay is added, and reloadData/didChangedPageIndex can be used to update the overlay based on browser state. ```swift class CloseButtonOverlay: UIView, JXPhotoBrowserOverlay { func setup(with browser: JXPhotoBrowserViewController) { // 在此完成布局(如添加约束) } func reloadData(numberOfItems: Int, pageIndex: Int) { // 数据或布局变化时更新 } func didChangedPageIndex(_ index: Int) { // 页码变化时更新 } } // 装载 browser.addOverlay(CloseButtonOverlay()) ``` -------------------------------- ### Configure Banner/Carousel Mode Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Setup for embedded carousel scenarios with auto-play and no transition animations. ```swift let banner = JXPhotoBrowserViewController() // 配置为轮播模式 banner.transitionType = .none // 无转场动画 banner.scrollDirection = .horizontal // 水平滚动 banner.isLoopingEnabled = true // 无限循环 banner.isAutoPlayEnabled = true // 自动轮播 banner.autoPlayInterval = 4.0 // 4 秒换一张 // 注册轻量级 Cell(无缩放功能) banner.register(JXImageCell.self, forReuseIdentifier: JXImageCell.reuseIdentifier) // 可选:添加页码指示器 banner.addOverlay(JXPageIndicatorOverlay()) banner.delegate = delegate // 通过 addSubview 等方式集成到页面 ``` -------------------------------- ### Configure Vertical Scrolling Mode Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Setup for vertical scrolling navigation without looping. ```swift let browser = JXPhotoBrowserViewController() browser.scrollDirection = .vertical // 竖版滚动 browser.transitionType = .fade browser.isLoopingEnabled = false // 竖版通常无循环 browser.delegate = delegate browser.present(from: self) ``` -------------------------------- ### Implement reloadData(numberOfItems:pageIndex:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md Example implementation for updating UI components when data or layout changes. ```swift func reloadData(numberOfItems: Int, pageIndex: Int) { pageControl.numberOfPages = numberOfItems pageControl.currentPage = min(pageIndex, max(numberOfItems - 1, 0)) // 仅一页时隐藏 isHidden = (numberOfItems <= 1) } ``` -------------------------------- ### Configure JXPageIndicatorOverlay Position Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/types.md Examples of setting the indicator position to top, bottom, or default values. ```swift let indicator = JXPageIndicatorOverlay() // 底部 20pt indicator.position = .bottom(padding: 20) // 顶部 10pt indicator.position = .top(padding: 10) // 使用默认位置 indicator.position = .default ``` -------------------------------- ### Custom Standalone Cell (Implementing JXPhotoBrowserCellProtocol) Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Implement the JXPhotoBrowserCellProtocol for complete control over a custom cell. This example shows how to provide a transition image and handle dismissal interaction changes. ```swift class StandaloneCell: UICollectionViewCell, JXPhotoBrowserCellProtocol { static let reuseIdentifier = "StandaloneCell" // 必须实现:弱引用浏览器(避免循环引用) weak var browser: JXPhotoBrowserViewController? // 可选实现:用于 Zoom 转场动画,返回 nil 则使用 Fade 动画 var transitionImageView: UIImageView? { imageView } let imageView = UIImageView() override init(frame: CGRect) { super.init(frame: frame) // 自定义初始化 } // 可选实现:下拉关闭交互状态变化时调用 // isInteracting 为 true 表示用户正在下拉(图片缩小跟随手指),false 表示交互结束(回弹恢复) // 下拉关闭仅会在图片处于最小缩放状态时触发 // 适用于在拖拽关闭过程中暂停视频、隐藏附加 UI 等场景 func photoBrowserDismissInteractionDidChange(isInteracting: Bool) { // 例如:下拉时暂停视频播放 } } ``` -------------------------------- ### Custom Video Player Cell (Inheriting JXZoomImageCell) Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Create a custom cell by inheriting JXZoomImageCell to add video playback capabilities. This example shows how to configure video resources and handle single taps for playback control or browser dismissal. ```swift class VideoPlayerCell: JXZoomImageCell { static let videoReuseIdentifier = "VideoPlayerCell" private var player: AVPlayer? private var playerLayer: AVPlayerLayer? override init(frame: CGRect) { super.init(frame: frame) // 自定义初始化:添加 loading 指示器等 } /// 配置视频资源 func configure(videoURL: URL, coverImage: UIImage? = nil) { imageView.image = coverImage // 创建播放器并开始播放... } /// 重写单击手势:暂停视频或关闭浏览器 override func handleSingleTap(_ gesture: UITapGestureRecognizer) { if isPlaying { pauseVideo() } else { browser?.dismissSelf() } } } ``` -------------------------------- ### Initialize JXPhotoBrowser with Basic Configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Standard initialization with delegate and transition settings. ```swift let browser = JXPhotoBrowserViewController() browser.initialIndex = 0 browser.delegate = MyPhotoBrowserDelegate() browser.transitionType = .fade browser.present(from: self) ``` -------------------------------- ### Initialize JXPhotoBrowser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/README.md Import the module and instantiate the view controller with basic configuration. ```swift import JXPhotoBrowser let browser = JXPhotoBrowserViewController() browser.delegate = ... browser.transitionType = .zoom browser.addOverlay(JXPageIndicatorOverlay()) ``` -------------------------------- ### Initialize JXPhotoBrowser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/README.md Create and present a basic photo browser instance. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = MyDelegate() browser.present(from: self) ``` -------------------------------- ### Presenting the Photo Browser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserViewController.md Initialize the browser and present it from a host view controller. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = self browser.present(from: self) ``` -------------------------------- ### Customize pageControl Appearance Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Example of modifying the colors of the internal page control. ```swift let indicator = JXPageIndicatorOverlay() indicator.pageControl.currentPageIndicatorTintColor = .white indicator.pageControl.pageIndicatorTintColor = .lightGray ``` -------------------------------- ### JXPhotoBrowserViewController Initialization Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/README.md How to initialize and present the JXPhotoBrowserViewController with custom configurations. ```APIDOC ## JXPhotoBrowserViewController Initialization ### Description Initialize the photo browser, configure its properties, and present it from a view controller. ### Configuration Properties - **delegate** (JXPhotoBrowserDelegate?) - Required - Data source delegate. - **initialIndex** (Int) - Optional - Initial display index (default: 0). - **scrollDirection** (JXPhotoBrowserScrollDirection) - Optional - Scrolling direction (default: .horizontal). - **isLoopingEnabled** (Bool) - Optional - Enable infinite looping (default: true). - **transitionType** (JXPhotoBrowserTransitionType) - Optional - Transition animation type (default: .fade). - **itemSpacing** (CGFloat) - Optional - Spacing between images (default: 0). - **isAutoPlayEnabled** (Bool) - Optional - Enable auto-play (default: false). - **autoPlayInterval** (TimeInterval) - Optional - Auto-play interval in seconds (default: 3.0). ### Example ```swift let browser = JXPhotoBrowserViewController() browser.delegate = MyDelegate() browser.initialIndex = 0 browser.transitionType = .zoom browser.isLoopingEnabled = true browser.addOverlay(JXPageIndicatorOverlay()) browser.present(from: self) ``` ``` -------------------------------- ### Basic Usage of JXPhotoBrowser Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Demonstrates how to create, configure, and present the JXPhotoBrowserViewController. ```swift import JXPhotoBrowser // 1. 创建浏览器实例 let browser = JXPhotoBrowserViewController() browser.delegate = self browser.initialIndex = indexPath.item // 设置初始索引 // 2. 配置选项(可选) browser.scrollDirection = .horizontal // 滚动方向 browser.transitionType = .zoom // 转场动画类型 browser.isLoopingEnabled = true // 是否开启无限循环 // 3. 展示 browser.present(from: self) ``` -------------------------------- ### Configure hidesForSinglePage Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Example of forcing the indicator to remain visible even with a single page. ```swift indicator.hidesForSinglePage = false // 始终显示 ``` -------------------------------- ### Full-screen image browsing configuration Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Default configuration for standard full-screen image viewing. ```swift browser.transitionType = .zoom browser.scrollDirection = .horizontal browser.isLoopingEnabled = true ``` -------------------------------- ### present(from:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserViewController.md Presents the photo browser from the specified view controller. ```APIDOC ## present(from:) ### Description Displays the photo browser from the provided host view controller. ### Method Swift Method ### Parameters - **vc** (UIViewController) - Required - The host view controller to present from. ### Example ```swift let browser = JXPhotoBrowserViewController() browser.delegate = self browser.present(from: self) ``` ``` -------------------------------- ### init() Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Convenience initializer for JXPageIndicatorOverlay, equivalent to calling init(frame: .zero). ```APIDOC ## init() ### Description Convenience initializer for JXPageIndicatorOverlay, equivalent to calling init(frame: .zero). ### Signature `public convenience init()` ### Example ```swift let indicator = JXPageIndicatorOverlay() browser.addOverlay(indicator) ``` ``` -------------------------------- ### Initialize Zoom Transition Browser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Uses zoom transition; requires the delegate to implement thumbnailViewAt and setThumbnailHidden. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = delegate browser.transitionType = .zoom // delegate 需实现 thumbnailViewAt 和 setThumbnailHidden browser.present(from: self) ``` -------------------------------- ### Implement photoBrowserDismissInteractionDidChange Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserCellProtocol.md Example of handling dismissal interaction state changes to adjust cell UI. ```swift func photoBrowserDismissInteractionDidChange(isInteracting: Bool) ``` ```swift class MyPhotoCell: UICollectionViewCell, JXPhotoBrowserCellProtocol { weak var browser: JXPhotoBrowserViewController? let imageView: UIImageView = UIImageView() var transitionImageView: UIImageView? { imageView } func photoBrowserDismissInteractionDidChange(isInteracting: Bool) { // 交互开始:禁用剪裁,允许图片超出边界 // 交互结束:恢复剪裁 imageView.clipsToBounds = !isInteracting } } ``` -------------------------------- ### Get Thumbnail Image for Index in PhotoPhotoBrowserDelegate Source: https://github.com/jiongxing/photobrowser/blob/master/CHANGELOG.md Protocol method for the PhotoPhotoBrowserDelegate to provide the thumbnail image associated with a specific image index. ```swift photoBrowser(_:, thumbnailImageForIndex:) ``` -------------------------------- ### Initialize Default Fullscreen Browser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Configures a standard horizontal browser with fade transitions and looping enabled. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = delegate browser.transitionType = .fade browser.scrollDirection = .horizontal browser.isLoopingEnabled = true browser.present(from: self) ``` -------------------------------- ### Get Thumbnail View for Index in PhotoPhotoBrowserDelegate Source: https://github.com/jiongxing/photobrowser/blob/master/CHANGELOG.md Protocol method for the PhotoPhotoBrowserDelegate to provide the thumbnail view associated with a specific image index. ```swift photoBrowser(_:, thumbnailViewForIndex:) ``` -------------------------------- ### Privacy Manifest Inclusion Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md The PrivacyInfo.xcprivacy file is included and explicitly configured in SwiftPM and CocoaPods setups, ensuring it's part of the distributed assets. ```text Privacy Manifest: PrivacyInfo.xcprivacy included and configured for distribution. ``` -------------------------------- ### Implementing JXPhotoBrowserDelegate Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Provides data and transition support by conforming to the JXPhotoBrowserDelegate protocol. Requires an image loading library like Kingfisher. ```swift import Kingfisher // 示例使用 Kingfisher,可替换为任意图片加载库 extension ViewController: JXPhotoBrowserDelegate { // 1. 返回图片总数 func numberOfItems(in browser: JXPhotoBrowserViewController) -> Int { return items.count } // 2. 提供用于展示的 Cell func photoBrowser(_ browser: JXPhotoBrowserViewController, cellForItemAt index: Int, at indexPath: IndexPath) -> JXPhotoBrowserAnyCell { let cell = browser.dequeueReusableCell(withReuseIdentifier: JXZoomImageCell.reuseIdentifier, for: indexPath) as! JXZoomImageCell return cell } // 3. 当 Cell 将要显示时加载图片 func photoBrowser(_ browser: JXPhotoBrowserViewController, willDisplay cell: JXPhotoBrowserAnyCell, at index: Int) { guard let photoCell = cell as? JXZoomImageCell else { return } let item = items[index] // 使用 Kingfisher 加载图片(可替换为 SDWebImage 或其他库) let placeholder = ImageCache.default.retrieveImageInMemoryCache(forKey: item.thumbnailURL.absoluteString) photoCell.imageView.kf.setImage(with: item.originalURL, placeholder: placeholder) { [weak photoCell] _ in photoCell?.setNeedsLayout() } } // 4. (可选) Cell 结束显示时清理资源(如取消加载、停止播放等) func photoBrowser(_ browser: JXPhotoBrowserViewController, didEndDisplaying cell: JXPhotoBrowserAnyCell, at index: Int) { // 可用于取消图片加载、停止视频播放等 } // 5. (可选) 支持 Zoom 转场:提供列表中的缩略图视图 func photoBrowser(_ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int) -> UIView? { let indexPath = IndexPath(item: index, section: 0) guard let cell = collectionView.cellForItem(at: indexPath) as? MyCell else { return nil } return cell.imageView } // 6. (可选) 控制缩略图显隐,避免 Zoom 转场时视觉重叠 func photoBrowser(_ browser: JXPhotoBrowserViewController, setThumbnailHidden hidden: Bool, at index: Int) { let indexPath = IndexPath(item: index, section: 0) if let cell = collectionView.cellForItem(at: indexPath) as? MyCell { cell.imageView.isHidden = hidden } } // 7. (可选) 自定义 Cell 尺寸,默认使用浏览器全屏尺寸 func photoBrowser(_ browser: JXPhotoBrowserViewController, sizeForItemAt index: Int) -> CGSize? { return nil // 返回 nil 使用默认尺寸 } } ``` -------------------------------- ### Initialize PhotoBrowser with Local Images Source: https://github.com/jiongxing/photobrowser/blob/master/CHANGELOG.md A convenience method to open the PhotoBrowser with a list of local images. This simplifies the process of displaying local image collections. ```swift PhotoBrowser.show(localImages:) ``` -------------------------------- ### Add a single overlay to JXPhotoBrowser Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserOverlay.md Instantiate the browser and add an overlay before presenting it. ```swift let browser = JXPhotoBrowserViewController() browser.addOverlay(JXPageIndicatorOverlay()) browser.present(from: self) ``` -------------------------------- ### Combine with Other Overlays Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Add multiple overlays to the browser instance simultaneously. ```swift let browser = JXPhotoBrowserViewController() browser.delegate = delegate // 页码指示器 let pageIndicator = JXPageIndicatorOverlay() pageIndicator.pageControl.currentPageIndicatorTintColor = .white pageIndicator.position = .bottom(padding: 12) // 标题 let titleLabel = UILabel() titleLabel.translatesAutoresizingMaskIntoConstraints = false titleLabel.textColor = .white titleLabel.font = .systemFont(ofSize: 14, weight: .medium) browser.addOverlay(pageIndicator) // 可添加其他自定义 Overlay... browser.present(from: self) ``` -------------------------------- ### Initialize JXImageCell Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Initialization methods for the cell. ```swift public override init(frame: CGRect) ``` ```swift public required init?(coder: NSCoder) ``` -------------------------------- ### View Documentation Directory Structure Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/INDEX.md Displays the file hierarchy of the generated documentation project. ```text output/ ├── README.md (总体导航和文档索引) ├── QUICK_REFERENCE.md (速查表和常见示例) ├── INDEX.md (本文件,文档导航和统计) ├── types.md (类型、枚举、别名) ├── configuration.md (配置参数和初始化指南) │ └── api-reference/ (API 详细文档) ├── JXPhotoBrowserViewController.md ├── JXPhotoBrowserDelegate.md ├── JXPhotoBrowserCellProtocol.md ├── JXZoomImageCell.md ├── JXImageCell.md ├── JXPhotoBrowserOverlay.md ├── JXPageIndicatorOverlay.md └── Animators.md ``` -------------------------------- ### Import JXPhotoBrowser Module Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Import the framework to access public types like JXPhotoBrowserViewController, JXPageIndicatorOverlay, and JXZoomImageCell. ```swift import JXPhotoBrowser // 使用所有公开类型 let browser = JXPhotoBrowserViewController() let indicator = JXPageIndicatorOverlay() let cell = JXZoomImageCell() ``` -------------------------------- ### Initialize JXPageIndicatorOverlay Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPageIndicatorOverlay.md Convenience initialization for the overlay component. ```swift let indicator = JXPageIndicatorOverlay() browser.addOverlay(indicator) ``` -------------------------------- ### Page Display Link Sequence Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md The sequence for displaying a page involves the host page initiating a thumbnail tap, creating and configuring JXPhotoBrowserViewController, presenting it, and then the browser laying out its collection view and loading media content via the delegate in willDisplay. ```text Host page taps thumbnail -> Create JXPhotoBrowserViewController -> Configure delegate, initialIndex, etc. -> present(from:) -> Transition animator intervenes -> Browser lays out collectionView -> Scroll to initial virtual index -> Delegate provides Cell -> willDisplay populates media content ``` -------------------------------- ### Full JXPhotoBrowser Implementation with Zoom Transition and Indicator Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Advanced implementation using Kingfisher for image loading, zoom transition support, and a page indicator overlay. ```swift import JXPhotoBrowser import Kingfisher class MyPhotoBrowserDelegate: NSObject, JXPhotoBrowserDelegate { var photos: [URL] = [] weak var collectionView: UICollectionView? func numberOfItems(in browser: JXPhotoBrowserViewController) -> Int { return photos.count } func photoBrowser( _ browser: JXPhotoBrowserViewController, cellForItemAt index: Int, at indexPath: IndexPath ) -> JXPhotoBrowserAnyCell { let cell = browser.dequeueReusableCell( withReuseIdentifier: JXZoomImageCell.reuseIdentifier, for: indexPath ) as! JXZoomImageCell cell.imageView.kf.setImage(with: photos[index]) return cell } // Zoom 转场支持 func photoBrowser( _ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int ) -> UIView? { let indexPath = IndexPath(item: index, section: 0) return (collectionView?.cellForItem(at: indexPath) as? PhotoCell)?.imageView } func photoBrowser( _ browser: JXPhotoBrowserViewController, setThumbnailHidden hidden: Bool, at index: Int ) { let indexPath = IndexPath(item: index, section: 0) (collectionView?.cellForItem(at: indexPath) as? PhotoCell)?.imageView.isHidden = hidden } } // 使用 let browser = JXPhotoBrowserViewController() browser.transitionType = .zoom browser.initialIndex = 0 browser.delegate = MyPhotoBrowserDelegate() let indicator = JXPageIndicatorOverlay() indicator.position = .bottom(padding: 16) browser.addOverlay(indicator) browser.present(from: self) ``` -------------------------------- ### Configure transition types in Swift Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/Animators.md Sets the transition animation style for the photo browser instance. ```swift let browser = JXPhotoBrowserViewController() // Fade 动画(渐隐渐现) browser.transitionType = .fade // Zoom 动画(缩放) browser.transitionType = .zoom // 无动画(直接显示/隐藏) browser.transitionType = .none ``` -------------------------------- ### Resource Pre-fetching Interface Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Consider adding an interface for pre-fetching resources based on the 'next appearing index'. This would optimize resource switching during large image browsing sessions. ```swift // Future enhancement: // Add an interface for pre-fetching resources based on upcoming indices. ``` -------------------------------- ### Implement thumbnailViewAt delegate method Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserDelegate.md Returns the source thumbnail view for Zoom transition animations. Returning nil causes the transition to fall back to a Fade animation. ```swift func photoBrowser( _ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int ) -> UIView? ``` ```swift func photoBrowser( _ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int ) -> UIView? { let indexPath = IndexPath(item: index, section: 0) guard let cell = collectionView.cellForItem(at: indexPath) as? PhotoCell else { return nil } return cell.thumbnailView } ``` -------------------------------- ### View Source Directory Structure Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/README.md Overview of the source files located in the Sources directory. ```text Sources/ ├── JXPhotoBrowserViewController.swift ├── JXPhotoBrowserDelegate.swift ├── JXPhotoBrowserCellProtocol.swift ├── JXPhotoBrowserOverlay.swift ├── JXZoomImageCell.swift ├── JXImageCell.swift ├── JXPageIndicatorOverlay.swift ├── JXPhotoBrowserTransitionType.swift ├── JXPhotoBrowserScrollDirection.swift ├── JXFadeAnimator.swift ├── JXNoneAnimator.swift ├── JXZoomPresentAnimator.swift └── JXZoomDismissAnimator.swift ``` -------------------------------- ### Implement Zoom animation configuration in Swift Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/Animators.md Provides the necessary delegate implementation to support zoom transitions, including thumbnail view mapping and visibility control. ```swift let browser = JXPhotoBrowserViewController() browser.transitionType = .zoom browser.initialIndex = 0 class MyDelegate: NSObject, JXPhotoBrowserDelegate { weak var sourceCollectionView: UICollectionView? func numberOfItems(in browser: JXPhotoBrowserViewController) -> Int { return photos.count } func photoBrowser( _ browser: JXPhotoBrowserViewController, cellForItemAt index: Int, at indexPath: IndexPath ) -> JXPhotoBrowserAnyCell { let cell = browser.dequeueReusableCell( withReuseIdentifier: JXZoomImageCell.reuseIdentifier, for: indexPath ) cell.imageView.image = photos[index] return cell } // Zoom 转场所需:返回源缩略图 func photoBrowser( _ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int ) -> UIView? { let indexPath = IndexPath(item: index, section: 0) guard let cell = sourceCollectionView?.cellForItem(at: indexPath) as? PhotoCell else { return nil } return cell.imageView } // Zoom 转场所需:控制源视图显隐 func photoBrowser( _ browser: JXPhotoBrowserViewController, setThumbnailHidden hidden: Bool, at index: Int ) { let indexPath = IndexPath(item: index, section: 0) if let cell = sourceCollectionView?.cellForItem(at: indexPath) as? PhotoCell { cell.imageView.isHidden = hidden } } } browser.delegate = MyDelegate() browser.present(from: self) ``` -------------------------------- ### Recommended Reuse: Business Logic and SwiftUI Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Manage image loading, caching, and cancellation within the business layer's `willDisplay` and `didEndDisplaying` methods. For SwiftUI projects, use the Presenter or a similar bridging layer to encapsulate the browser's entry point. ```swift // In business layer: func willDisplay(cell: JXPhotoBrowserCell, for item: Int) { /* Load image */ } func didEndDisplaying(cell: JXPhotoBrowserCell, for item: Int) { /* Cancel loading */ } // In SwiftUI project: let presenter = PhotoBrowserPresenter() presenter.present(from: self) ``` -------------------------------- ### Configure auto-play Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md Manages automatic image cycling and interval timing. ```swift // 启用 browser.isAutoPlayEnabled = true // 停止 browser.isAutoPlayEnabled = false // 调整轮播间隔(需要重启轮播生效) browser.autoPlayInterval = 2.0 browser.isAutoPlayEnabled = false browser.isAutoPlayEnabled = true // 重启 ``` -------------------------------- ### Configure Zoom Transition Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/README.md Enable zoom transition type. Requires implementing thumbnailViewAt and setThumbnailHidden in the delegate. ```swift browser.transitionType = .zoom // delegate 中实现 thumbnailViewAt 和 setThumbnailHidden ``` -------------------------------- ### Configure asynchronous loading with indicators Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Enable the loading indicator and manage state during asynchronous image fetching within the willDisplay delegate method. ```swift func photoBrowser( _ browser: JXPhotoBrowserViewController, willDisplay cell: JXPhotoBrowserAnyCell, at index: Int ) { guard let imageCell = cell as? JXImageCell else { return } imageCell.isLoadingIndicatorEnabled = true imageCell.startLoading() // 异步加载图片 imageLoader.loadImage(for: index) { [weak imageCell] result in DispatchQueue.main.async { if case .success(let image) = result { imageCell?.imageView.image = image } imageCell?.stopLoading() } } } ``` -------------------------------- ### Configure JXImageCell for banner scenarios Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Set up the JXPhotoBrowserViewController for non-fullscreen, auto-playing banner views using JXImageCell. ```swift // JXImageCell 可用于 PhotoBannerView 等嵌入式场景(无全屏浏览) let banner = JXPhotoBrowserViewController() banner.scrollDirection = .horizontal banner.transitionType = .none banner.isLoopingEnabled = true banner.isAutoPlayEnabled = true banner.autoPlayInterval = 3.0 // 注册 Cell banner.register(JXImageCell.self, forReuseIdentifier: JXImageCell.reuseIdentifier) ``` -------------------------------- ### Implement basic JXImageCell usage Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXImageCell.md Use the JXPhotoBrowserDelegate to dequeue and configure JXImageCell for standard image display. ```swift class MyBrowserDelegate: NSObject, JXPhotoBrowserDelegate { var photos: [UIImage] = [] func numberOfItems(in browser: JXPhotoBrowserViewController) -> Int { return photos.count } func photoBrowser( _ browser: JXPhotoBrowserViewController, cellForItemAt index: Int, at indexPath: IndexPath ) -> JXPhotoBrowserAnyCell { let cell = browser.dequeueReusableCell( withReuseIdentifier: JXImageCell.reuseIdentifier, for: indexPath ) as! JXImageCell cell.imageView.image = photos[index] return cell } } ``` -------------------------------- ### 管理 Overlay 组件 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md 使用 addOverlay 和 removeOverlay 方法动态管理浏览器上的覆盖层组件。 ```swift browser.addOverlay(JXPageIndicatorOverlay()) browser.addOverlay(MyCustomOverlay()) ``` ```swift browser.removeOverlay(overlay) ``` -------------------------------- ### Calling JXPhotoBrowser from SwiftUI View Source: https://github.com/jiongxing/photobrowser/blob/master/README.md Demonstrates how to integrate JXPhotoBrowser into a SwiftUI View using a presenter. The presenter must be held by a @State variable due to the weak delegate reference. ```swift struct ContentView: View { // 持有 presenter(JXPhotoBrowserViewController.delegate 为 weak,需要外部强引用) @State private var presenter: PhotoBrowserPresenter? var body: some View { LazyVGrid(columns: columns) { ForEach(Array(items.enumerated()), id: \.element.id) { index, item in AsyncImage(url: item.thumbnailURL) .onTapGesture { let p = PhotoBrowserPresenter(items: items) presenter = p p.present(initialIndex: index) } } } } } ``` -------------------------------- ### View and Controller Hierarchy Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/types.md Visual representation of the inheritance and protocol implementation relationships within the library. ```text UIViewController ↑ └─ JXPhotoBrowserViewController UIView ├─ UICollectionViewCell │ ├─ JXZoomImageCell (implement JXPhotoBrowserCellProtocol) │ └─ JXImageCell (implement JXPhotoBrowserCellProtocol) │ → UICollectionViewCell & JXPhotoBrowserCellProtocol = JXPhotoBrowserAnyCell │ └─ (any UIView implement JXPhotoBrowserOverlay) ├─ JXPageIndicatorOverlay └─ Custom overlays NSObject ├─ JXFadeAnimator (implement UIViewControllerAnimatedTransitioning) ├─ JXNoneAnimator (implement UIViewControllerAnimatedTransitioning) ├─ JXZoomPresentAnimator (implement UIViewControllerAnimatedTransitioning) └─ JXZoomDismissAnimator (implement UIViewControllerAnimatedTransitioning) ``` -------------------------------- ### 导入 JXPhotoBrowser 模块 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/types.md 通过导入 JXPhotoBrowser 模块即可使用库中所有公开类型。 ```swift import JXPhotoBrowser // 所有类型自动可用 let browser = JXPhotoBrowserViewController() browser.transitionType = .zoom browser.scrollDirection = .horizontal let indicator = JXPageIndicatorOverlay() ``` -------------------------------- ### 配置转场动画 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md 设置 transitionType 以更改转场效果,使用 .zoom 模式时需在代理中实现对应的缩略图方法。 ```swift browser.transitionType = .zoom ``` -------------------------------- ### JXZoomImageCell Initial Layout Logic Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Describes the initial layout strategy for JXZoomImageCell, which uses a long-edge fitting approach similar to AspectFit. This ensures the image is fully visible and serves as the baseline for subsequent double-tap zoom actions. ```text 初始布局根据图片和容器的宽高比计算缩放比例,默认使用接近 `AspectFit` 的逻辑,使图片完整进入视野,并作为后续双击切换的基准状态。 ``` -------------------------------- ### Implement a simple photo cell Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserCellProtocol.md A basic cell implementation providing a transition image view for the browser. ```swift class SimplePhotoCell: UICollectionViewCell, JXPhotoBrowserCellProtocol { let imageView = UIImageView() override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(imageView) imageView.frame = contentView.bounds imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight] imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } var transitionImageView: UIImageView? { imageView } } ``` -------------------------------- ### 配置初始显示索引 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/configuration.md 设置 initialIndex 以指定打开浏览器时显示的图片位置。 ```swift browser.initialIndex = 5 // 打开时显示第 6 张图片 ``` -------------------------------- ### thumbnailViewAt Delegate Method Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/QUICK_REFERENCE.md Provides the thumbnail view to the browser for transition animations. ```APIDOC ## photoBrowser(_:thumbnailViewAt:) ### Description Required to provide the source view for the `.zoom` transition animation. The framework handles the coordinate conversion automatically. ### Signature `func photoBrowser(_ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int) -> UIView?` ### Example ```swift func photoBrowser(_ browser: JXPhotoBrowserViewController, thumbnailViewAt index: Int) -> UIView? { let indexPath = IndexPath(item: index, section: 0) guard let cell = collectionView.cellForItem(at: indexPath) as? PhotoCell else { return nil } return cell.imageView } ``` ``` -------------------------------- ### JXPhotoBrowser Architecture Overview Source: https://github.com/jiongxing/photobrowser/blob/master/TECHNICAL_SOLUTION.md Illustrates the layered architecture of JXPhotoBrowser, showing the separation of concerns between the host page, delegate, view controller, and its plugins like overlays and animators. It highlights the role of UICollectionView for paging and the JXPhotoBrowserCellProtocol for cell customization. ```text 宿主页面 / 业务数据 | v JXPhotoBrowserDelegate | v JXPhotoBrowserViewController | | | | | +-- Overlay 插件体系 | +-- 转场动画器(Zoom/Fade/None) +-- UICollectionView 分页与复用 | +-- JXPhotoBrowserCellProtocol | +-- JXZoomImageCell +-- JXImageCell +-- 自定义 Cell(如 VideoPlayerCell) ``` -------------------------------- ### Adding an Overlay Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserViewController.md Attach an overlay component to the browser to display UI elements like page indicators. ```swift let browser = JXPhotoBrowserViewController() browser.addOverlay(JXPageIndicatorOverlay()) ``` -------------------------------- ### 获取滚动方向计算属性 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/types.md 获取 UICollectionView 对应的滚动方向和滚动位置。 ```swift var flowDirection: UICollectionView.ScrollDirection ``` ```swift var scrollPosition: UICollectionView.ScrollPosition ``` -------------------------------- ### photoBrowser(_:thumbnailViewAt:) Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserDelegate.md Returns the thumbnail view for the specified index in the source list, used for zoom transition animation start/end positions. ```APIDOC ## photoBrowser(_:thumbnailViewAt:) ### Description Returns the thumbnail view for the specified index. Used for Zoom transition animation start/end positions. ### Parameters - **browser** (JXPhotoBrowserViewController) - The browser instance. - **index** (Int) - The real data source index. ### Returns - **UIView?** - The thumbnail view, or nil if the transition should fallback to a Fade animation. ``` -------------------------------- ### 定义 JXPhotoBrowser 类型与枚举 Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/00_START_HERE.md 定义了转场动画类型和滚动方向的枚举,用于配置浏览器的行为。 ```swift enum JXPhotoBrowserTransitionType { case fade, zoom, none } enum JXPhotoBrowserScrollDirection { case horizontal, vertical } ``` -------------------------------- ### Extend JXPhotoBrowserCellProtocol with default implementations Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserCellProtocol.md Provides optional default implementations for protocol properties and methods, allowing for minimal cell definitions. ```swift public extension JXPhotoBrowserCellProtocol { var browser: JXPhotoBrowserViewController? { get { nil } set { } } var transitionImageView: UIImageView? { nil } func photoBrowserDismissInteractionDidChange(isInteracting: Bool) {} } ``` -------------------------------- ### UIViewControllerTransitioningDelegate Methods Source: https://github.com/jiongxing/photobrowser/blob/master/_autodocs/api-reference/JXPhotoBrowserViewController.md Methods for providing custom animation controllers for presenting and dismissing the view controller. ```APIDOC ## animationController(forPresented:presenting:source:) ### Description Returns the appropriate animation controller for presenting the view controller based on the `transitionType`. ## animationController(forDismissed:) ### Description Returns the appropriate animation controller for dismissing the view controller based on the `transitionType`. ```