### Install MJRefresh using Carthage Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This snippet demonstrates how to integrate MJRefresh into your project using Carthage. Carthage is a decentralized dependency manager for macOS and iOS. ```bash github "CoderMJLee/MJRefresh" ``` -------------------------------- ### Install ZFPlayer via CocoaPods Source: https://context7.com/renzifeng/zfplayer/llms.txt Configure the Podfile to include specific ZFPlayer subspecs based on required functionality, such as core features, default UI controls, or specific player backends. ```ruby # Core player template only pod 'ZFPlayer', '~> 4.0' # With default control view UI pod 'ZFPlayer/ControlView', '~> 4.0' # With AVPlayer support pod 'ZFPlayer/AVPlayer', '~> 4.0' # With ijkplayer support pod 'ZFPlayer/ijkplayer', '~> 4.0' ``` -------------------------------- ### Initialize ZFPlayerController (List Style) Source: https://github.com/renzifeng/zfplayer/blob/master/README.md Provides examples for initializing ZFPlayerController when integrating with scrollable views like UITableView or UICollectionView. It supports specifying a container view tag or directly providing the container view. ```objc ZFPlayerController *player = [ZFPlayerController playerWithScrollView:tableView playerManager:playerManager containerViewTag:containerViewTag]; ZFPlayerController *player = [ZFPlayerController alloc] initWithScrollView:tableView playerManager:playerManager containerViewTag:containerViewTag]; ZFPlayerController *player = [ZFPlayerController playerWithScrollView:scrollView playerManager:playerManager containerView:containerView]; ZFPlayerController *player = [ZFPlayerController alloc] initWithScrollView:tableView playerManager:playerManager containerView:containerView]; ``` -------------------------------- ### Install MJRefresh using CocoaPods Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This snippet shows how to install the MJRefresh library into your iOS project using CocoaPods. Ensure you have CocoaPods installed and configured in your project. ```bash pod 'MJRefresh' ``` -------------------------------- ### Install ZFPlayer via CocoaPods Source: https://github.com/renzifeng/zfplayer/blob/master/README.md This snippet shows how to add the ZFPlayer library to your project using CocoaPods. It includes options for the core player, default control view, AVPlayer integration, and ijkplayer integration. ```objc pod 'ZFPlayer', '~> 4.0' pod 'ZFPlayer/ControlView', '~> 4.0' pod 'ZFPlayer/AVPlayer', '~> 4.0' pod 'ZFPlayer/ijkplayer', '~> 4.0' ``` -------------------------------- ### TableView Cell Configuration for ZFPlayer (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Configures a UITableViewCell to host a video player. It includes a UIImageView that serves as the container for the video, identified by a specific tag (kPlayerViewTag). This setup is crucial for ZFPlayer to correctly attach and manage the video playback within the cell. ```objc // VideoTableViewCell.h @interface VideoTableViewCell : UITableViewCell @property (nonatomic, strong) UIImageView *coverImageView; @end // VideoTableViewCell.m static NSInteger const kPlayerViewTag = 100; @implementation VideoTableViewCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Create cover image view as player container self.coverImageView = [[UIImageView alloc] init]; self.coverImageView.userInteractionEnabled = YES; self.coverImageView.tag = kPlayerViewTag; // Important: set tag for player self.coverImageView.contentMode = UIViewContentModeScaleAspectFill; self.coverImageView.clipsToBounds = YES; [self.contentView addSubview:self.coverImageView]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; CGFloat width = self.contentView.bounds.size.width; CGFloat height = width * 9.0 / 16.0; // 16:9 aspect ratio self.coverImageView.frame = CGRectMake(0, 10, width, height); } @end ``` -------------------------------- ### Initialize Basic Video Player with AVPlayer Source: https://context7.com/renzifeng/zfplayer/llms.txt Set up a standard video player instance by configuring the player manager, container view, and control interface within a UIViewController. ```objective-c #import #import #import @interface VideoViewController () @property (nonatomic, strong) ZFPlayerController *player; @property (nonatomic, strong) UIView *containerView; @property (nonatomic, strong) ZFPlayerControlView *controlView; @end @implementation VideoViewController - (void)viewDidLoad { [super viewDidLoad]; self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 88, self.view.bounds.size.width, self.view.bounds.size.width * 9/16)]; [self.view addSubview:self.containerView]; ZFAVPlayerManager *playerManager = [[ZFAVPlayerManager alloc] init]; playerManager.shouldAutoPlay = YES; self.player = [ZFPlayerController playerWithPlayerManager:playerManager containerView:self.containerView]; self.controlView = [[ZFPlayerControlView alloc] init]; self.controlView.autoHiddenTimeInterval = 5.0; self.controlView.autoFadeTimeInterval = 0.5; self.controlView.prepareShowLoading = YES; self.player.controlView = self.controlView; NSURL *videoURL = [NSURL URLWithString:@"https://example.com/video.mp4"]; self.player.assetURL = videoURL; [self.controlView showTitle:@"Video Title" coverURLString:@"https://example.com/cover.jpg" fullScreenMode:ZFFullScreenModeAutomatic]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.player.viewControllerDisappear = NO; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.player.viewControllerDisappear = YES; } @end ``` -------------------------------- ### Initialize ZFPlayerController (Normal Style) Source: https://github.com/renzifeng/zfplayer/blob/master/README.md Demonstrates two ways to initialize the main ZFPlayerController for standard video playback. It requires a player manager and a container view. ```objc ZFPlayerController *player = [ZFPlayerController playerWithPlayerManager:playerManager containerView:containerView]; ZFPlayerController *player = [[ZFPlayerController alloc] initwithPlayerManager:playerManager containerView:containerView]; ``` -------------------------------- ### Configure ZFPlayerControlView appearance and behavior Source: https://context7.com/renzifeng/zfplayer/llms.txt This snippet demonstrates how to initialize and configure the ZFPlayerControlView, including setting auto-hide intervals, loading behavior, and handling callbacks for user interactions like back button clicks and visibility changes. ```Objective-C ZFPlayerControlView *controlView = [[ZFPlayerControlView alloc] init]; // Auto-hide timing controlView.autoHiddenTimeInterval = 5.0; // Hide controls after 5 seconds controlView.autoFadeTimeInterval = 0.5; // Fade animation duration // Loading and preparation controlView.prepareShowLoading = YES; // Show loading during preparation controlView.prepareShowControlView = NO; // Don't show controls during preparation // Fast forward/rewind animation controlView.fastViewAnimated = YES; // Seek behavior controlView.seekToPlay = YES; // Resume play after seeking when paused // Background blur effect controlView.effectViewShow = YES; // Custom status bar in fullscreen (iOS 13+) controlView.showCustomStatusBar = YES; // Pan gesture shows controls controlView.horizontalPanShowControlView = YES; // Set video info [controlView showTitle:@"Video Title" coverURLString:@"https://example.com/cover.jpg" fullScreenMode:ZFFullScreenModeAutomatic]; // Reset control view [controlView resetControlView]; // Control view visibility callback controlView.controlViewAppearedCallback = ^(BOOL appeared) { NSLog(@"Control view %@", appeared ? @"shown" : @"hidden"); }; ``` -------------------------------- ### Implement custom player engine with ZFPlayerMediaPlayback Source: https://context7.com/renzifeng/zfplayer/llms.txt This snippet shows how to create a custom player manager by conforming to the ZFPlayerMediaPlayback protocol. It requires synthesizing necessary state properties and implementing core playback methods like play, pause, stop, and seekToTime. ```Objective-C @interface CustomPlayerManager : NSObject @end @implementation CustomPlayerManager @synthesize view = _view, isPlaying = _isPlaying, assetURL = _assetURL; - (void)play { _isPlaying = YES; if (self.playerPlayStateChanged) { self.playerPlayStateChanged(self, ZFPlayerPlayStatePlaying); } } - (void)pause { _isPlaying = NO; if (self.playerPlayStateChanged) { self.playerPlayStateChanged(self, ZFPlayerPlayStatePaused); } } - (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^)(BOOL))completionHandler { _currentTime = time; if (completionHandler) { completionHandler(YES); } } @end ``` -------------------------------- ### Monitor ZFPlayer Playback States with Callbacks (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Implement block-based callbacks to monitor various player states including preparation, readiness, playback progress, buffering, play state changes, load state, playback failures, and video size changes. These callbacks allow for real-time updates and UI synchronization. ```objc self.player.playerPrepareToPlay = ^(id asset, NSURL *assetURL) { NSLog(@"Preparing to play: %@", assetURL); }; self.player.playerReadyToPlay = ^(id asset, NSURL *assetURL) { NSLog(@"Ready to play, duration: %.2f seconds", asset.totalTime); }; self.player.playerPlayTimeChanged = ^(id asset, NSTimeInterval currentTime, NSTimeInterval duration) { NSLog(@"Progress: %.2f / %.2f", currentTime, duration); CGFloat progress = duration > 0 ? currentTime / duration : 0; }; self.player.playerBufferTimeChanged = ^(id asset, NSTimeInterval bufferTime) { NSLog(@"Buffer time: %.2f seconds", bufferTime); }; self.player.playerPlayStateChanged = ^(id asset, ZFPlayerPlaybackState playState) { switch (playState) { case ZFPlayerPlayStatePlaying: NSLog(@"Playing"); break; case ZFPlayerPlayStatePaused: NSLog(@"Paused"); break; case ZFPlayerPlayStatePlayFailed: NSLog(@"Failed"); break; case ZFPlayerPlayStatePlayStopped: NSLog(@"Stopped"); break; default: break; } }; self.player.playerLoadStateChanged = ^(id asset, ZFPlayerLoadState loadState) { if (loadState & ZFPlayerLoadStatePlayable) { NSLog(@"Playable"); } if (loadState & ZFPlayerLoadStateStalled) { NSLog(@"Stalled - buffering"); } }; self.player.playerPlayFailed = ^(id asset, id error) { NSLog(@"Playback failed: %@", error); }; self.player.presentationSizeChanged = ^(id asset, CGSize size) { NSLog(@"Video size: %.0f x %.0f", size.width, size.height); }; ``` -------------------------------- ### Manage Video Playlist Navigation Source: https://context7.com/renzifeng/zfplayer/llms.txt Configure the player to handle an array of video URLs, enabling sequential playback, manual navigation, and event handling for when a video finishes. ```objective-c NSArray *assetURLs = @[ [NSURL URLWithString:@"https://example.com/video1.mp4"], [NSURL URLWithString:@"https://example.com/video2.mp4"], [NSURL URLWithString:@"https://example.com/video3.mp4"] ]; self.player.assetURLs = assetURLs; [self.player playTheIndex:0]; @zf_weakify(self) self.player.playerDidToEnd = ^(id asset) { @zf_strongify(self) if (!self.player.isLastAssetURL) { [self.player playTheNext]; NSString *title = [NSString stringWithFormat:@"Video %zd", self.player.currentPlayIndex + 1]; [self.controlView showTitle:title coverURLString:@"https://example.com/cover.jpg" fullScreenMode:ZFFullScreenModeLandscape]; } else { [self.player stop]; } }; - (void)playPrevious { if (!self.player.isFirstAssetURL) { [self.player playThePrevious]; } } - (void)playAtIndex:(NSInteger)index { [self.player playTheIndex:index]; } ``` -------------------------------- ### Configure Screen Rotation and Fullscreen Modes in ZFPlayer (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Demonstrates how to control fullscreen behavior, including automatic detection, forcing landscape or portrait modes, and handling rotation animations and callbacks. It also covers locking screen orientation and configuring the status bar. ```objc // Configure fullscreen mode // ZFFullScreenModeAutomatic - Auto-detect based on video dimensions // ZFFullScreenModeLandscape - Force landscape fullscreen // ZFFullScreenModePortrait - Portrait fullscreen (like TikTok) // Rotate to landscape fullscreen [self.player rotateToOrientation:UIInterfaceOrientationLandscapeRight animated:YES]; // Rotate with completion handler [self.player rotateToOrientation:UIInterfaceOrientationLandscapeLeft animated:YES completion:^{ NSLog(@"Rotation completed"); }]; // Enter portrait fullscreen (for vertical videos) [self.player enterPortraitFullScreen:YES animated:YES]; // Generic fullscreen toggle (respects fullScreenMode setting) [self.player enterFullScreen:YES animated:YES completion:^{ NSLog(@"Entered fullscreen"); }]; // Exit fullscreen [self.player enterFullScreen:NO animated:YES completion:nil]; // Lock screen orientation self.player.lockedScreen = YES; // Configure fullscreen status bar self.player.fullScreenStatusBarStyle = UIStatusBarStyleLightContent; self.player.fullScreenStatusBarAnimation = UIStatusBarAnimationSlide; self.player.statusBarHidden = NO; // Auto exit fullscreen when stopped self.player.exitFullScreenWhenStop = YES; // Orientation change callbacks self.player.orientationWillChange = ^(ZFPlayerController *player, BOOL isFullScreen) { NSLog(@"Will change to fullscreen: %d", isFullScreen); }; self.player.orientationDidChanged = ^(ZFPlayerController *player, BOOL isFullScreen) { NSLog(@"Did change to fullscreen: %d", isFullScreen); if (isFullScreen) { // Show fullscreen-only UI elements } else { // Show normal UI elements } }; // Add device orientation observer for auto-rotation [self.player addDeviceOrientationObserver]; // Remove when not needed [self.player removeDeviceOrientationObserver]; ``` -------------------------------- ### Import MJRefresh Header File Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This code snippet shows how to import the main header file for MJRefresh after manually adding the library files to your project. This makes all MJRefresh components available for use. ```objc #import "MJRefresh.h" ``` -------------------------------- ### Configure Small Floating Window Playback Source: https://context7.com/renzifeng/zfplayer/llms.txt Enables and manages the floating window feature for continuous playback when scrolling away from the primary video container. Includes methods for manual view transitions and visibility status monitoring. ```Objective-C // Enable floating window (disable stopWhileNotVisible) self.player.stopWhileNotVisible = NO; // Access small float view ZFFloatView *floatView = self.player.smallFloatView; // Check if float view is showing BOOL isFloating = self.player.isSmallFloatViewShow; // Manually add player to float view [self.player addPlayerViewToSmallFloatView]; // Return player to cell [self.player addPlayerViewToCell]; // Return player to container view [self.player addPlayerViewToContainerView:self.containerView]; // Configure control view for float mode self.controlView.floatControlView; // Access float control view // Stop current playing cell [self.player stopCurrentPlayingCell]; // Stop current playing view [self.player stopCurrentPlayingView]; // Float view visibility callbacks in custom control - (void)videoPlayer:(ZFPlayerController *)videoPlayer floatViewShow:(BOOL)show { if (show) { NSLog(@"Float view appeared"); } else { NSLog(@"Float view disappeared"); } } ``` -------------------------------- ### Configure Background Playback in ZFPlayer Source: https://context7.com/renzifeng/zfplayer/llms.txt This snippet shows how to configure ZFPlayer for background audio playback. It includes settings to allow background playback, use a custom audio session, manually configure the audio session, and handle app state changes to update now playing information. ```Objective-C // Allow background playback self.player.pauseWhenAppResignActive = NO; // Custom audio session (disable ZFPlayer's default configuration) self.player.customAudioSession = YES; // Configure audio session manually NSError *error = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeMoviePlayback options:0 error:&error]; [[AVAudioSession sharedInstance] setActive:YES error:&error]; // Handle app state changes self.player.playerPlayStateChanged = ^(id asset, ZFPlayerPlaybackState playState) { // Update now playing info for lock screen if (playState == ZFPlayerPlayStatePlaying) { [self updateNowPlayingInfo]; } }; ``` -------------------------------- ### Manage Multi-Section TableView URLs Source: https://context7.com/renzifeng/zfplayer/llms.txt Configures video data sources for complex table views containing multiple sections. Demonstrates how to map nested URL arrays to index paths and trigger playback with specific scroll positioning. ```Objective-C // For single-section tableviews, use assetURLs self.player.assetURLs = @[url1, url2, url3]; // For multi-section tableviews, use sectionAssetURLs NSArray *> *sectionURLs = @[ @[section0_url1, section0_url2], // Section 0 @[section1_url1, section1_url2, section1_url3], // Section 1 @[section2_url1] // Section 2 ]; self.player.sectionAssetURLs = sectionURLs; // Play specific indexPath with URL NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0]; NSURL *videoURL = sectionURLs[indexPath.section][indexPath.row]; [self.player playTheIndexPath:indexPath assetURL:videoURL scrollPosition:ZFPlayerScrollViewScrollPositionTop animated:YES completionHandler:^{ NSLog(@"Scroll and play completed"); }]; ``` -------------------------------- ### Conform to ZFPlayerMediaPlayback Protocol Source: https://github.com/renzifeng/zfplayer/blob/master/README.md Illustrates how to declare a player manager that conforms to the ZFPlayerMediaPlayback protocol. This protocol enables support for various player SDKs beyond the default AVPlayer. ```objc Class *playerManager = ...; ``` -------------------------------- ### Control ZFPlayer Playback Position and Timing (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Manage video playback by accessing current playback information such as current time, total duration, and buffer time. Seek to specific times or percentages of the total duration with optional completion handlers. Control playback speed, volume, brightness, and mute status. ```objc NSTimeInterval currentTime = self.player.currentTime; NSTimeInterval totalTime = self.player.totalTime; NSTimeInterval bufferTime = self.player.bufferTime; float progress = self.player.progress; // 0.0 - 1.0 float bufferProgress = self.player.bufferProgress; // 0.0 - 1.0 [self.player seekToTime:30.0 completionHandler:^(BOOL finished) { if (finished) { NSLog(@"Seek completed successfully"); } else { NSLog(@"Seek was interrupted or failed"); } }]; - (void)seekToProgress:(float)progress { NSTimeInterval seekTime = self.player.totalTime * progress; [self.player seekToTime:seekTime completionHandler:nil]; } self.player.currentPlayerManager.rate = 1.5; self.player.volume = 0.8; // Device volume (0.0 - 1.0) self.player.brightness = 0.7; // Screen brightness (0.0 - 1.0) self.player.muted = NO; // Mute toggle ``` -------------------------------- ### MJRefresh Header and Footer Classes Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This lists the primary classes provided by MJRefresh for implementing pull-to-refresh and infinite scrolling. It categorizes them into normal and GIF variations for both headers and footers, including auto-refresh and auto-back options. ```text MJRefreshNormalHeader MJRefreshGifHeader MJRefreshAutoNormalFooter MJRefreshAutoGifFooter MJRefreshBackNormalFooter MJRefreshBackGifFooter ``` -------------------------------- ### Implement ScrollView Visibility Callbacks Source: https://context7.com/renzifeng/zfplayer/llms.txt Tracks video player visibility within UITableView or UICollectionView using percentage-based callbacks and lifecycle events. Allows for intelligent filtering of playback triggers during and after scrolling. ```Objective-C // Player appearing callback (with percentage) self.player.zf_playerAppearingInScrollView = ^(NSIndexPath *indexPath, CGFloat appearPercent) { NSLog(@"Cell at %@ appearing: %.0f%%", indexPath, appearPercent * 100); }; // Player disappearing callback (with percentage) self.player.zf_playerDisappearingInScrollView = ^(NSIndexPath *indexPath, CGFloat disappearPercent) { NSLog(@"Cell at %@ disappearing: %.0f%%", indexPath, disappearPercent * 100); }; // Player will appear self.player.zf_playerWillAppearInScrollView = ^(NSIndexPath *indexPath) { NSLog(@"Player will appear at: %@", indexPath); }; // Player did appear self.player.zf_playerDidAppearInScrollView = ^(NSIndexPath *indexPath) { NSLog(@"Player did appear at: %@", indexPath); }; // Player will disappear self.player.zf_playerWillDisappearInScrollView = ^(NSIndexPath *indexPath) { NSLog(@"Player will disappear from: %@", indexPath); }; // Player did disappear self.player.zf_playerDidDisappearInScrollView = ^(NSIndexPath *indexPath) { NSLog(@"Player did disappear from: %@", indexPath); }; // Filter cells for playback while scrolling [self.player zf_filterShouldPlayCellWhileScrolling:^(NSIndexPath *indexPath) { NSLog(@"Should play cell at: %@", indexPath); [self playVideoAtIndexPath:indexPath]; }]; // Filter cells for playback when scroll stops [self.player zf_filterShouldPlayCellWhileScrolled:^(NSIndexPath *indexPath) { NSLog(@"Play after scroll stopped at: %@", indexPath); [self playVideoAtIndexPath:indexPath]; }]; // Currently playing index path NSIndexPath *playingPath = self.player.playingIndexPath; // Should play index path NSIndexPath *shouldPlayPath = self.player.shouldPlayIndexPath; ``` -------------------------------- ### Assign Custom Control View Source: https://github.com/renzifeng/zfplayer/blob/master/README.md Shows how to assign a custom control view to the ZFPlayerController. The custom control view must conform to the ZFPlayerMediaControl protocol. ```objc UIView *controlView = ...; player.controlView = controlView; ``` -------------------------------- ### Configure AVPlayer-Specific Features in ZFPlayer Source: https://context7.com/renzifeng/zfplayer/llms.txt This snippet demonstrates how to access and configure AVPlayer-specific properties and features using ZFAVPlayerManager. It covers setting custom HTTP headers, time refresh intervals, accessing underlying AVPlayer components, enabling Picture-in-Picture, capturing thumbnails, and setting scaling modes. ```Objective-C ZFAVPlayerManager *avManager = [[ZFAVPlayerManager alloc] init]; // Set custom HTTP headers for video requests avManager.requestHeader = @{ @"Authorization": @"Bearer token123", @"Custom-Header": @"value" }; // Set time refresh interval (default is 0.1) avManager.timeRefreshInterval = 0.5; self.player = [ZFPlayerController playerWithPlayerManager:avManager containerView:self.containerView]; // Access underlying AVPlayer components AVPlayer *player = avManager.player; AVPlayerItem *playerItem = avManager.playerItem; AVURLAsset *asset = avManager.asset; AVPlayerLayer *playerLayer = avManager.avPlayerLayer; // Picture-in-Picture support (iOS 9+) if ([AVPictureInPictureController isPictureInPictureSupported]) { AVPictureInPictureController *pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer:avManager.avPlayerLayer]; // Start PiP after a short delay dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [pipController startPictureInPicture]; }); } // Get current video thumbnail UIImage *thumbnail = [avManager thumbnailImageAtCurrentTime]; // Or async version [avManager thumbnailImageAtCurrentTime:^(UIImage *image) { self.thumbnailImageView.image = image; }]; // Set scaling mode avManager.scalingMode = ZFPlayerScalingModeAspectFit; // Fit with letterbox avManager.scalingMode = ZFPlayerScalingModeAspectFill; // Fill with crop avManager.scalingMode = ZFPlayerScalingModeFill; // Stretch to fill avManager.scalingMode = ZFPlayerScalingModeNone; // No scaling ``` -------------------------------- ### Implement Automatic Refresh Footer for UITableView (Objective-C) Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This snippet demonstrates how to set up an automatic refresh footer for a UITableView using MJDIYAutoFooter. This allows for custom pull-to-refresh behavior. It requires the MJRefresh library. ```objective-c self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; // Implementation reference to MJDIYAutoFooter.h和MJDIYAutoFooter.m ``` -------------------------------- ### Configure Gesture Controls in ZFPlayer (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Details how to disable specific gestures (tap, pan, pinch, long press), customize pan gesture behavior for seeking, volume, and brightness, and set custom trigger conditions for gestures within ZFPlayer. ```objc // Disable specific gestures self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPan; // Disable pan self.player.disableGestureTypes = ZFPlayerDisableGestureTypesDoubleTap; // Disable double tap self.player.disableGestureTypes = ZFPlayerDisableGestureTypesAll; // Disable all gestures self.player.disableGestureTypes = ZFPlayerDisableGestureTypesNone; // Enable all gestures // Disable pan in specific directions self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionVertical; self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionHorizontal; self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionAll; // Access gesture control directly ZFPlayerGestureControl *gestureControl = self.player.gestureControl; // Single tap callback gestureControl.singleTapped = ^(ZFPlayerGestureControl *control) { NSLog(@"Single tap - show/hide controls"); }; // Double tap callback gestureControl.doubleTapped = ^(ZFPlayerGestureControl *control) { NSLog(@"Double tap - toggle play/pause"); }; // Pan gesture callbacks for seek/volume/brightness gestureControl.beganPan = ^(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location) { if (direction == ZFPanDirectionH) { NSLog(@"Horizontal pan started - seeking"); } else if (direction == ZFPanDirectionV) { if (location == ZFPanLocationLeft) { NSLog(@"Vertical pan on left - brightness"); } else { NSLog(@"Vertical pan on right - volume"); } } }; gestureControl.changedPan = ^(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location, CGPoint velocity) { NSLog(@"Pan changed with velocity: (%.2f, %.2f)", velocity.x, velocity.y); }; gestureControl.endedPan = ^(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location) { NSLog(@"Pan ended"); }; // Pinch gesture for zoom gestureControl.pinched = ^(ZFPlayerGestureControl *control, float scale) { NSLog(@"Pinch scale: %.2f", scale); }; // Long press gesture gestureControl.longPressed = ^(ZFPlayerGestureControl *control, ZFLongPressGestureRecognizerState state) { switch (state) { case ZFLongPressGestureRecognizerStateBegan: NSLog(@"Long press began"); break; case ZFLongPressGestureRecognizerStateChanged: NSLog(@"Long press changed"); break; case ZFLongPressGestureRecognizerStateEnded: NSLog(@"Long press ended"); break; } }; // Gesture trigger condition gestureControl.triggerCondition = ^BOOL(ZFPlayerGestureControl *control, ZFPlayerGestureType type, UIGestureRecognizer *gesture, UITouch *touch) { // Return NO to prevent gesture return YES; }; ``` -------------------------------- ### Implement Pull-to-Refresh and Drop-down Refresh for UICollectionView (Objective-C) Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This code illustrates how to add both drop-down refresh (header) and pull-to-refresh (footer) functionalities to a UICollectionView using MJRefreshNormalHeader and MJRefreshAutoNormalFooter. It requires the MJRefresh library. ```objective-c // The drop-down refresh self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ //Call this Block When enter the refresh status automatically }]; // The pull to refresh self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ //Call this Block When enter the refresh status automatically }]; ``` -------------------------------- ### TableView List Playback with ZFPlayer (Objective-C) Source: https://context7.com/renzifeng/zfplayer/llms.txt Integrates ZFPlayer into a UITableView for list playback. It configures the player to automatically play/pause videos based on cell visibility during scrolling. Dependencies include ZFPlayerController and ZFAVPlayerManager. It requires a tagged container view within each cell. ```objc static NSInteger const kPlayerViewTag = 100; @interface TableViewController () @property (nonatomic, strong) UITableView *tableView; @property (nonatomic, strong) ZFPlayerController *player; @property (nonatomic, strong) ZFPlayerControlView *controlView; @property (nonatomic, strong) NSArray *dataSource; @end @implementation TableViewController - (void)viewDidLoad { [super viewDidLoad]; ZFAVPlayerManager *playerManager = [[ZFAVPlayerManager alloc] init]; // Initialize player for scroll view with container tag self.player = [ZFPlayerController playerWithScrollView:self.tableView playerManager:playerManager containerViewTag:kPlayerViewTag]; self.player.controlView = self.controlView; // Configure visibility percentages self.player.playerDisapperaPercent = 0.4; // Stop when 40% off screen self.player.playerApperaPercent = 0.6; // Play when 60% visible // Enable auto-play on cellular network self.player.WWANAutoPlay = YES; // Enable resume playback from last position self.player.resumePlayRecord = YES; // Callback when scrolling stops - find best cell to play @zf_weakify(self) self.player.zf_scrollViewDidEndScrollingCallback = ^(NSIndexPath *indexPath) { @zf_strongify(self) if (!self.player.playingIndexPath) { [self playVideoAtIndexPath:indexPath]; } }; // Auto-play while scrolling self.player.zf_playerShouldPlayInScrollView = ^(NSIndexPath *indexPath) { @zf_strongify(self) if ([indexPath compare:self.player.playingIndexPath] != NSOrderedSame) { [self playVideoAtIndexPath:indexPath]; } }; // Handle playback completion self.player.playerDidToEnd = ^(id asset) { @zf_strongify(self) [self.player stopCurrentPlayingCell]; }; } - (void)playVideoAtIndexPath:(NSIndexPath *)indexPath { VideoModel *model = self.dataSource[indexPath.row]; NSURL *videoURL = [NSURL URLWithString:model.videoURL]; // Play with scroll position [self.player playTheIndexPath:indexPath assetURL:videoURL scrollPosition:ZFPlayerScrollViewScrollPositionCenteredVertically animated:YES]; // Update control view [self.controlView showTitle:model.title coverURLString:model.coverURL fullScreenMode:ZFFullScreenModeLandscape]; } #pragma mark - UIScrollViewDelegate (Required for list playback) - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [scrollView zf_scrollViewDidEndDecelerating]; } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { [scrollView zf_scrollViewDidEndDraggingWillDecelerate:decelerate]; } - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView { [scrollView zf_scrollViewDidScrollToTop]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [scrollView zf_scrollViewDidScroll]; } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [scrollView zf_scrollViewWillBeginDragging]; } @end ``` -------------------------------- ### Implement Drop-down Refresh for WKWebView (Objective-C) Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This snippet shows how to add a drop-down refresh header to the scroll view of a WKWebView using MJRefreshNormalHeader. This enables pull-to-refresh functionality for web content. It requires the MJRefresh library. ```objective-c //Add the control of The drop-down refresh self.webView.scrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ //Call this Block When enter the refresh status automatically }]; ``` -------------------------------- ### Implement Automatic Back Refresh Footer for UITableView (Objective-C) Source: https://github.com/renzifeng/zfplayer/blob/master/Example/Pods/MJRefresh/README.md This snippet shows how to configure an automatic back refresh footer for a UITableView using MJDIYBackFooter. This provides a different style of pull-to-refresh behavior. It depends on the MJRefresh library. ```objective-c self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; // Implementation reference to MJDIYBackFooter.h和MJDIYBackFooter.m ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.