IRIPCamera is a powerful URL/Rtsp/IPCam player/viewer for iOS.
Display | Setting |
---|---|
IRPlayer
+ Live555
+ iOS Native API.
Live555
can make a connection with a rtsp server/streaming.IRPlayer
is the video player which can receive the frames and play it.
IRFFVideoInput
.H264-RTSP-Server-iOS
as a RTSP IPCamera and IRIPCamera
as a RTSP Player.
Stickers | After effections |
---|---|
demo
and ScreenShots
folder.pod 'IRSticker-swift'
in the Podfile
pod install
import IRSticker_swift
let sticker1 = IRStickerView.init(frame: CGRect.init(x: 0, y: 0, width: 150, height: 150), contentImage: UIImage.init(named: "sticker1.png")!)
sticker1.center = self.view.center
sticker1.enabledControl = false
sticker1.enabledBorder = false
sticker1.tag = 1
sticker1.delegate = self
self.view.addSubview(sticker1)
IRStickerViewDelegate
, see in the demo project.public protocol IRStickerViewDelegate: NSObjectProtocol {
func ir_StickerViewDidTapContentView(stickerView: IRStickerView)
func ir_StickerView(stickerView: IRStickerView, imageForLeftTopControl recommendedSize: CGSize) -> UIImage?
func ir_StickerViewDidTapLeftTopControl(stickerView: IRStickerView) // Effective when image is provided.
func ir_StickerView(stickerView: IRStickerView, imageForRightTopControl recommendedSize: CGSize) -> UIImage?
func ir_StickerViewDidTapRightTopControl(stickerView: IRStickerView) // Effective when image is provided.
func ir_StickerView(stickerView: IRStickerView, imageForLeftBottomControl recommendedSize: CGSize) -> UIImage?
func ir_StickerViewDidTapLeftBottomControl(stickerView: IRStickerView) // Effective when image is provided.
func ir_StickerView(stickerView: IRStickerView, imageForRightBottomControl recommendedSize: CGSize) -> UIImage?
func ir_StickerViewDidTapRightBottomControl(stickerView: IRStickerView) // Effective when image is provided.
}
Demo Main Page | Enable Face Sticker |
---|---|
Confirm | Custom filters |
Custom filters | Update display view |
demo
and ScreenShots
folder.pod 'IREffectCamera'
in the Podfile
pod install
#import <IRCameraSticker/IRCameraSticker.h>
#import <IRCameraSticker/IRCameraStickerFilter.h>
#import <IRCameraSticker/IRCameraStickersManager.h>
...
- (IBAction)faceStickerTapped {
[_camera displayFaceSticker];
}
Custom image filters(You can see how GPUImage work in the demo project):
YES
by customizePhotoProcessingView
in the IRCameraDelegate
to disable the default filters
#pragma mark - IRCameraDelegate
- (BOOL)customizePhotoProcessingView {
return YES;
}
#import <GPUImage/GPUImage.h>
- (UIImage *)imageWithSketchFilter:(UIImage *)originImage {
GPUImageFilter *imageFilter = [[GPUImageSketchFilter alloc] init];
return [imageFilter imageByFilteringImage:originImage];
}
demo
and ScreenShots
folder.pod 'IRCameraSticker'
in the Podfile
pod install
IRTabbedPageViewController is a UIViewController that provides a simple to implement page view controller with scrolling tab bar. It also includes a UIPageViewController wrapper that provides improved data source and delegation methods.
pod 'IRTabbedPageViewController'
in the Podfile
pod install
To use the tabbed page view controller, simply create a UIViewController
that is a subclass of IRTabbedPageViewController
. Then implement the following data source method:
// array of view controllers to display in page view controller
- (NSArray *)viewControllersForPageViewController:(IRPageViewController *)pageViewController;
If you are using a UINavigationController
(As shown in Example project) you can embed the tab bar in the navigation bar. Simply set the UINavigationBar
class in the navigation controller to IRTabNavigationBar
and the navigation bar will attach to the view controller.
To manually attach a tab bar view to the IRTabbedPageViewController
:
tabBarView
property of the IRTabbedPageViewController
to an IRTabBarView
instance (Note: tabBarView
is weak and an IBOutlet
).dataSource
and delegate
properties of the IRTabBarView
instance to the IRTabbedPageViewController
(Both are IBOutlet
able).To customise the content of the tabs in the tab bar override the following:
- (void)tabBarView:(IRTabBarView *)tabBarView
populateTab:(IRTabBarCollectionViewCell *)tab
atIndex:(NSInteger)index;
IRPageViewController is a UIViewController wrapper for UIPageViewController that provides a simpler data source and enhanced delegation methods. The data source methods are encapsulated in the IRTabbedPageViewControllerDataSource
as seen above.
The delegate methods that IRPageViewControllerDelegate
provides are listed below:
- (void)pageViewController:(IRPageViewController *)pageViewController
didScrollToPageOffset:(CGFloat)pageOffset
direction:(IRPageViewControllerScrollDirection)scrollDirection;
Called when the page view controller is scrolled by the user to a specific offset, similar to scrollViewDidScroll
. The pageOffset maintains the current page position and a scroll direction is provided.
- (void)pageViewController:(IRPageViewController *)pageViewController
didScrollToPage:(NSInteger)page;
Called when the page view controller completes a full scroll to a new page.
IRTabBarView
provides properties for appearance customisation, including:
sizingStyle
- Whether the tab bar should size to fit or equally distribute its tabs.tabStyle
- The styles to use for tabs:
IRTabStyleText
for text.IRTabStyleImage
for images.IRTabStyleImageAndText
for images and text.IRTabStyleCustomView
for custom view.indicatorStyle
- The style to use for the current tab indicator.indicatorAttributes
- Appearance attributes for current tab indicator.tabAttributes
- Appearance attributes for tabs.selectedTabAttributes
- Appearance attributes for the selected tab.selectionIndicatorTransitionStyle
- The transition style for the selection indicator.IRTabTransitionStyleProgressive
to progressively transition between tabs.IRTabTransitionStyleSnap
to snap between tabs during transitioning.setTransitionStyle:
to set both the selectionIndicatorTransitionStyle
and tabTransitionStyle
.tabTransitionStyle
- The transition style to use for the tabs.Set custom tab view in the IRTabBarViewDataSource
.
#pragma mark - IRTabBarViewDataSource
- (void)tabBarView:(IRTabBarView *)tabBarView populateTab:(IRTabBarCollectionViewCell *)tab atIndex:(NSInteger)index {
tab.customView = YOUR_CUSTOM_TAB_VIEW;
}
Main Page | Failure |
---|---|
Sequential Requesting | Sequential Success |
Concurent Requesting | Concurent Success |
Observer Pattern
, it is a good feature to send messages between classes and not break you codes structure, but sometimes you have a lot of notifications and want to manage them, like network relative notifications.pod 'IRNotificationReceiver'
in the Podfile
pod install
demo
project display a situation for network requests. You want to use notifications to deliver the status of requests, they could be success or failure, and called by sequential or concurent. Use IRNotificationReceiver
can be eazy to manage these notifications.NotificationReceiver
#import <IRNotificationReceiver/IRNotificationReceiver.h>
#define GetUserProfileSuccessNotification @"GetUserProfileSuccessNotification"
#define GetFriendsSuccessNotification @"GetFriendsSuccessNotification"
#define GetMessagesSuccessNotification @"GetMessagesSuccessNotification"
NotificationReceiver *notificationReceiver = [[NotificationReceiver alloc] init];
notificationReceiver.repeat = NO;
notificationReceiver.delegate = self;
The default value of repeat
is YES
, that means once the conditions are completed, the NotificationReceiver
will reset and look forward the same conditions again. The situation is use for some the same requests you want to do again, ex: Click a button do 3 requests A, B, C, show the result after the requests are completed, then you can click again.
The default value of enable
is YES
, if set to NO
, The NotificationReceiverDelegate
will not be called, and checkConditionsWith
not work too.
addObserver
, and set NotificationConditioner
[notificationReceiver addObserver:self selector:@selector(completionNotifications:) conditioner:[[NotificationConditioner alloc] initWithName:GetUserProfileSuccessNotification minCount:1] ignoreable:YES object:nil];
ignoreable
YES
, while you call ignoreConditionerWithName
or ignoreConditioner
, the specific notification would not manage by checkConditionsWith
. It also triger the ignore delegaet: receivedIgnoreConditionerWithName:(NSString*)name
in the NotificationReceiverDelegate
.minCount
minCount
to help you promise the number of specific notification are called if verified by checkConditionsWith
.checkConditionsWith
checkConditionsWith
, the common way is put the codes in the call back of the requests.checkConditionsWith
would consume the minCount
in the NotificationConditioner
. That means if you set a Login NotificationConditioner
with 3 for minCount
, after you call checkConditionsWith:@"Login"
three times, the check result would be verified.[notificationReceiver checkConditionsWith:name verifity:^(BOOL isVerified) {
if(name) {
self.statusLabel.text = [self.statusLabel.text stringByAppendingString:[NSString stringWithFormat:@"%@ %@\n", [name stringByReplacingOccurrencesOfString:@"SuccessNotification" withString:@""], @"Success."]];
}
if(isVerified) {
[self didUpdate];
}
}];
resetConditioners
resetConditioners
to make the conditions reset to default. Ex: Click logout button, discard all of the network requests and reset the conditions.removeObserver
SharedNotificationConditioner
.
Login
. You just want to do it once, so if logined, then do something, else do Login
.SharedNotificationConditioner
for Login
request in the all of the pages that you want to login first. Like Profile page, Friends page, etc….[notificationReceiver addObserver:self selector:@selector(completionNotifications:) conditioner:[[SharedNotificationConditioner sharedInstance] sharedNotificationConditionerWithName:LoginSuccessNotification minCount:1] ignoreable:YES object:nil];
PhotoManageViewController | PhotoManageBrowser |
---|---|
Camera | Album |
PhotoGalleryViewController | Full Screen Gallery |
pod 'IRPhotoGallery'
in the Podfile
pod install
PhotoManageViewController
, it include multi parts: Gallery, Preview, Camera, Album, Filters, etc…NSBundle *bundle = [NSBundle bundleForClass:[PhotoManageViewController class]];
photoManageViewController = [[PhotoManageViewController alloc] initWithNibName:@"PhotoManageViewController" bundle:bundle];
photoManageViewController.delegate = self;
photoManageViewController.cameraDelegate = self;
[IRCameraColor setTintColor: [UIColor whiteColor]];
[self.navigationController pushViewController:photoManageViewController animated:YES];
PhotoManageBrowser
, it just a gallery viewphotoManageBrowser = [[PhotoManageBrowser alloc] init];
[photoManageBrowser setStyle:Normal];
[photoManageBrowser setDirection:ScrollDirectionHorizontal];
__weak ViewController* wSelf = self;
[photoManageBrowser setItemSelectedBlock:^(NSIndexPath *indexPath) {
NSBundle *bundle = [NSBundle bundleForClass:[PhotoGalleryViewController class]];
PhotoGalleryViewController* photoGalleryViewController = [[PhotoGalleryViewController alloc] initWithNibName:@"PhotoGalleryViewController" bundle:bundle];
photoGalleryViewController.delegate = wSelf;
photoGalleryViewController.imageIndex = indexPath.row;
[wSelf presentViewController:photoGalleryViewController animated:YES completion:nil];
}];
photoManageBrowser.delegate = self;
[self.view addSubview:photoManageBrowser];
PhotoManageViewController |
---|
Normal |
Deletable |
Scalable |
[photoManageBrowser setStyle:Normal];
PhotoManageBrowserScrollDirection |
---|
ScrollDirectionVertical |
ScrollDirectionHorizontal |
[photoManageBrowser setDirection:ScrollDirectionHorizontal];
#pragma mark - PhotoManageBrowserDelegate
- (NSUInteger)numberOfPhotos {
return photos.count;
}
- (NSString *)titleOfPhotoWithIndex:(NSInteger)index {
return [photos objectAtIndex:index].note;
}
- (id)imageOrPathStringOfPhotoWithIndex:(NSInteger)index {
return [images objectAtIndex:index];
}
#pragma mark - CameraViewControllerDelegate
- (void)didTakePhoto:(UIImage *)image Note:(NSString *)note {
Photo *photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:context];
photo.photo = UIImagePNGRepresentation(image);
photo.note = note;
[(AppDelegate *)[[UIApplication sharedApplication] delegate] saveContext];
[self reloadPhotos];
[photoManageViewController reloadUI];
}
- (void)doUpdatePhoto:(UIImage *)image Note:(NSString *)note Completed:(nullable IRCompletionBlock)completedBlock {
[photoManageViewController showLoading:YES];
NSInteger index = [images indexOfObject:image];
Photo *photo = [photos objectAtIndex:index];
photo.photo = UIImagePNGRepresentation(image);
photo.note = note;
[(AppDelegate *)[[UIApplication sharedApplication] delegate] saveContext];
if (completedBlock) {
completedBlock(YES);
}
[photoManageViewController reloadUI];
[photoManageViewController showLoading:NO];
}
- (void)doDeletePhoto:(UIImage *)image {
NSInteger index = [images indexOfObject:image];
Photo *photo = [photos objectAtIndex:index];
[context deleteObject:photo];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] saveContext];
[self reloadPhotos];
[photoManageViewController reloadUI];
}
PhotoManageBrowser
, 4 blocks let you override the default feature@property (nonatomic, copy) CurrentPageChangedBlock currentPageChangedBlock;
@property (nonatomic, copy) ItemSelectedBlock itemSelectedBlock;
@property (nonatomic, copy) DeleteClickBlock deleteClickBlock;
@property (nonatomic, copy) EditClickBlock editClickBlock;
PhotoGalleryViewController
, it is a simple gallery view controllerNSBundle *bundle = [NSBundle bundleForClass:[PhotoGalleryViewController class]];
PhotoGalleryViewController* photoGalleryViewController = [[PhotoGalleryViewController alloc] initWithNibName:@"PhotoGalleryViewController" bundle:bundle];
photoGalleryViewController.delegate = wSelf;
photoGalleryViewController.imageIndex = indexPath.row;
[wSelf presentViewController:photoGalleryViewController animated:YES completion:nil];
Demo1 | Demo2 |
---|---|
Demo3 | Demo4 |
self.tableView = [[BranchTableIView alloc] init];
self.tableView.delegate = self;
Device *devicebranch1 = [[Device alloc] init];
devicebranch1.name = @"branch1";
Device *devicebranch2 = [[Device alloc] init];
devicebranch2.name = @"branch2";
Device *devicebranch3 = [[Device alloc] init];
devicebranch3.name = @"branch3";
Device *devicebranch4 = [[Device alloc] init];
devicebranch4.name = @"branch4";
Device *devicebranch5 = [[Device alloc] init];
devicebranch5.name = @"branch5";
Device *deviceleaf = [[Device alloc] init];
deviceleaf.name = @"leaf";
Device *deviceleaf2 = [[Device alloc] init];
deviceleaf2.name = @"leaf2";
Device *deviceleaf3 = [[Device alloc] init];
deviceleaf3.name = @"leaf3";
Device *deviceleaf4 = [[Device alloc] init];
deviceleaf4.name = @"leaf4";
Device *deviceleaf5 = [[Device alloc] init];
deviceleaf5.name = @"leaf5";
Device *deviceleaf6 = [[Device alloc] init];
deviceleaf6.name = @"leaf6";
Device *deviceleaf7 = [[Device alloc] init];
deviceleaf7.name = @"leaf7";
Device *deviceleaf8 = [[Device alloc] init];
deviceleaf8.name = @"leaf8";
Device *deviceleaf9 = [[Device alloc] init];
deviceleaf9.name = @"leaf9";
Device *deviceleaf10 = [[Device alloc] init];
deviceleaf10.name = @"leaf10";
Device *deviceleaf11 = [[Device alloc] init];
deviceleaf11.name = @"leaf11";
Device *deviceleaf12 = [[Device alloc] init];
deviceleaf12.name = @"leaf12";
branch = [[Branch alloc] initWithTableView:self.tableView];
Branch *branch1 = [[Branch alloc] initWithDevice:devicebranch1];
Branch *branch2 = [[Branch alloc] initWithDevice:devicebranch2];
Branch *branch3 = [[Branch alloc] initWithDevice:devicebranch3];
Branch *branch4 = [[Branch alloc] initWithDevice:devicebranch4];
Branch *branch5 = [[Branch alloc] initWithDevice:devicebranch5];
Leaf *leaf = [[Leaf alloc] initWithDevice:deviceleaf];
Leaf *leaf2 = [[Leaf alloc] initWithDevice:deviceleaf2];
Leaf *leaf3 = [[Leaf alloc] initWithDevice:deviceleaf3];
Leaf *leaf4 = [[Leaf alloc] initWithDevice:deviceleaf4];
Leaf *leaf5 = [[Leaf alloc] initWithDevice:deviceleaf5];
Leaf *leaf6 = [[Leaf alloc] initWithDevice:deviceleaf6];
Leaf *leaf7 = [[Leaf alloc] initWithDevice:deviceleaf7];
Leaf *leaf8 = [[Leaf alloc] initWithDevice:deviceleaf8];
Leaf *leaf9 = [[Leaf alloc] initWithDevice:deviceleaf9];
Leaf *leaf10 = [[Leaf alloc] initWithDevice:deviceleaf10];
Leaf *leaf11 = [[Leaf alloc] initWithDevice:deviceleaf11];
Leaf *leaf12 = [[Leaf alloc] initWithDevice:deviceleaf12];
FunctionModelBranchItem *branchItem = [[FunctionModelBranchItem alloc] initWithRowCount:1];
[model addItem:branchItem];
[branch add:leaf];
[branch add:branch1];
[branch add:leaf2];
[branch1 add:branch2];
[branch1 add:leaf3];
[branch1 add:leaf4];
[branch2 add:leaf5];
[branch2 add:leaf6];
[branch2 add:branch3];
[branch3 add:leaf7];
[branch3 add:leaf8];
[branch2 add:branch4];
[branch4 add:leaf9];
[branch2 add:branch5];
[branch5 add:leaf10];
[branch5 add:leaf11];
[branch5 add:leaf12];
[self.view addSubview:self.tableView];
BranchTableIView
.IRHierarchyTreeTableView can nice combine with another powerful tableview/collectionview framework:IRCollectionTableViewModel.
self.tableView = [[BranchTableIView alloc] init];
model = [[Model alloc] init];
model.delegate = self;
self.tableView.dataSource = model;
TableView | CollectionView |
---|---|
TableViewViewModel
extends TableViewBasicViewModel<UITableViewDataSource>
, and Import IRCollectionTableViewModel
#import <IRCollectionTableViewModel/IRCollectionTableViewModel.h>
@interface TableViewViewModel : TableViewBasicViewModel<UITableViewDataSource>
@end
- (instancetype)initWithTableView:(UITableView*)tableView;
...
- (instancetype)initWithTableView:(UITableView *)tableView {
if (self = [super init]) {
items = [[NSMutableArray<id<SectionModelItem>> alloc] init];
[tableView registerNib:[UINib nibWithNibName:CELL_NIB_NAME bundle:nil] forCellReuseIdentifier:CELL_IDENTIFIER];
}
return self;
}
update
method- (void)update;
...
- (void)update {
[items removeAllObjects];
// Setup items
// [self setupRows];
}
items
, other words, setup the sections/rows you want to show. Create TableViewSectionItem
and TableViewRowItem
, DemoSectionType
, DemoRowType
typedef NS_ENUM(NSInteger, DemoSectionType){
DemoSection
};
typedef NS_ENUM(NSInteger, DemoRowType){
RowType_DemoRow
};
@interface TableViewRowItem : RowBasicModelItem
@property (readonly) DemoRowType type;
@end
@interface TableViewSectionItem : SectionBasicModelItem
@property (nonatomic) NSString* sectionTitle;
@property (nonatomic) SectionType type;
@end
TableViewSectionItem
and TableViewRowItem
in the TableViewViewModel.m
@implementation TableViewRowItem
@dynamic type;
@end
@implementation TableViewSectionItem
@end
items
- (void)setupRows {
NSMutableArray *rowItems = [NSMutableArray array];
[rowItems addObject:[[TableViewRowItem alloc] initWithType:RowType_DemoRow withTitle:@"Demo Row"]];
[rowItems addObject:[[TableViewRowItem alloc] initWithType:RowType_DemoRow withTitle:@"Demo Row"]];
NSArray *demoRowItems = [NSArray arrayWithArray:rowItems];
TableViewSectionItem *item = [[TableViewSectionItem alloc] initWithRowCount:[demoRowItems count]];
item.type = DemoSection;
item.sectionTitle = @"Demo Section";
item.rows = demoRowItems;
[items addObject:item];
}
UITableViewDataSource
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return items.count;
}
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [items[section] rowCount];
}
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
id<SectionModelItem> item = [items objectAtIndex:indexPath.section];
TableViewRowItem *row = (TableViewRowItem *)[item.rows objectAtIndex:[indexPath row]];
switch (item.type) {
case DemoSection:
{
switch (row.type) {
case RowType_DemoRow:
{
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:TableViewCell.identifier forIndexPath:indexPath];
cell.titleLabel.text = [NSString stringWithFormat:@"%@%ld", row.title, row.tagRange.location];
cell.editTextField.text = [editedTexts objectAtIndex:indexPath.row];
cell.editTextField.tag = row.tagRange.location;
cell.editTextField.delegate = self;
return cell;
}
}
break;
}
default:
break;
}
return [[UITableViewCell alloc] init];
}
TableViewViewModel
#import "TableViewViewModel.h"
@implementation TableViewController {
TableViewViewModel *viewModel;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:HEADER_VIEW_NIB_NAME bundle:nil] forHeaderFooterViewReuseIdentifier:HEADER_VIEW_IDENTIFIER];
viewModel = [[TableViewViewModel alloc] initWithTableView:_tableView];
_tableView.dataSource = viewModel;
[viewModel update];
}
@end
Just the same way of TableViewViewModel
. Create a new class CustomCollectionViewModel
extends TableViewBasicViewModel<UICollectionViewDataSource>
, and Import this CustomCollectionViewModel
to view controller
You can add your init method and register the cell inside
For setup items
, other words, setup the sections/rows you want to show. Create CustomCollectionSectionItem
and CustomCollectionRowItem
, CustomCollectionSectionType
Override UICollectionViewDataSource
TableViewBasicViewModel
provides some usage methods- (NSInteger)getRowTypeWith:(SectionType)type row:(NSInteger)row;
- (NSString *)getSectionTitleinSection:(NSInteger)section;
- (UIImage *)getSectionLeftIconinSection:(NSInteger)section;
- (SectionType)getSectionTypeinSection:(NSInteger)section;
- (void)hideRows:(BOOL)hide inSection:(NSInteger)section;
- (BOOL)hiddenRowsinSection:(NSInteger)section;
- (NSIndexSet *)getIndexSetWithSectionType:(SectionType)sectionType;
- (NSIndexPath *)getIndexPathWithSectionType:(SectionType)sectionType rowType:(RowType)rowType;
- (void)setupRowTag;
- (NSIndexPath *)getIndexPathFromRowTag:(NSInteger)rowTag;
Because the cells have reuse feature, somtimes we need to tag the cell/componenst if want to recognize the specific cell/components, thus IRCollectionTableViewModel
provides a tag feature
Setup tags by setupRowTag
, it save the tag information in the tagRange
which is in the RowBasicModelItem
- (void)setupRows {
...
[self setupRowTag];
}
TableViewRowItem *row = (TableViewRowItem *)[item.rows objectAtIndex:[indexPath row]];
tag = row.tagRange.location;
- (NSIndexPath *)getIndexPathFromRowTag:(NSInteger)rowTag;
UITextField
, use setTagRangeLength
TableViewRowItem *row = [[TableViewRowItem alloc] initWithType:RowType_DemoRow withTitle:@"Demo Row"];
[row setTagRangeLength:2];
...
[self setupRowTag];
TableViewRowItem *row = (TableViewRowItem *)[item.rows objectAtIndex:[indexPath row]];
tag1 = row.tagRange.location;
tag2 = row.tagRange.location + 1;
cell.textField1.tag = tag1;
cell.textField2.tag = tag2;
[self getIndexPathFromRowTag:tag1] == [self getIndexPathFromRowTag:tag2]
Now, you can easy to tag anyhing you want.
(void)hideRows:(BOOL)hide inSection:(NSInteger)section
- (NSInteger)getRowTypeWith:(SectionType)type row:(NSInteger)row;
SectionBasicModelItem
- (NSString *)getSectionTitleinSection:(NSInteger)section;
SectionBasicModelItem
- (UIImage *)getSectionLeftIconinSection:(NSInteger)section;
- (SectionType)getSectionTypeinSection:(NSInteger)section;
(void)hideRows:(BOOL)hide inSection:(NSInteger)section
(BOOL)hiddenRowsinSection:(NSInteger)section
- (void)hideRows:(BOOL)hide inSection:(NSInteger)section;
- (BOOL)hiddenRowsinSection:(NSInteger)section;
- (NSIndexSet *)getIndexSetWithSectionType:(SectionType)sectionType;
- (NSIndexPath *)getIndexPathWithSectionType:(SectionType)sectionType rowType:(RowType)rowType;
Normal | VR |
---|---|
VR Box | Fisheye 360 |
Panorama | Modes Selection |
Multi Windows | |
Support Normal video mode.
Support VR mode.
Support VR Box mode.
Support Fisheye mode.
Support multi windows.
Support multi modes selection.
0.3.6
pod 'IRPlayer', '~> 0.3.2'
in the Podfile
pod install
self.player = [IRPlayerImp player];
[self.mainView insertSubview:self.player.view atIndex:0];
NSURL * normalVideo = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"i-see-fire" ofType:@"mp4"]];
NSURL * vrVideo = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"google-help-vr" ofType:@"mp4"]];
NSURL * fisheyeVideo = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"fisheye-demo" ofType:@"mp4"]];
IRFFVideoInput *input = [[IRFFVideoInput alloc] init];
[self.player replaceVideoWithInput:input videoType:IRVideoTypeNormal];
...
IRFFAVYUVVideoFrame * yuvFrame = [[IRFFAVYUVVideoFrame alloc] init];
/*
setup the yuvFrame.
*/
[input updateFrame:frame];
List | Gallery |
---|---|
Delete | Favorite |
Share | Scale |
Landscape |
---|
Show Alert for XFDialogBuilder | Show Custom View for XFDialogBuilder |
---|---|
Show Alert for LGAlert | Show Custom View for LGAlert |
Show System Action Sheet | Show System Alert |
Main Page | Show System Alert And Loding Page |
The demo
show three diffrent alert systems, include Apple system alert
, XFDialogBuilder
, and LGAlertView
.
Assum you want to handle with a alert system named DEMOAlert
, you can follow as below:
Create a new class IRDEMOAlert
extends IRAlert
, and Import IRAlertManager
#import <IRAlertManager/IRAlertManager.h>
typedef NS_ENUM(NSUInteger, IRDEMOAlertStyle) {
IRDEMOAlertStyleAlert = 0,
IRDEMOAlertStyleActionSheet = 1
};
@interface IRDEMOAlert : IRAlert
- (instancetype)initWithTitle:(nullable NSString *)title
message:(nullable NSString *)message
style:(IRDEMOAlertStyle)style
buttonActions:(nullable NSArray<IRAlertAction *> *)buttonActions
cancelButtonAction:(nullable IRAlertAction *)cancelButtonAction
destructiveButtonAction:(nullable IRAlertAction *)destructiveButtonAction;
@end
DEMOAlert
instanse inside- (instancetype)initWithTitle:(nullable NSString *)title
message:(nullable NSString *)message
style:(IRAlertLGStyle)style
buttonActions:(nullable NSArray<IRAlertAction *> *)buttonActions
cancelButtonAction:(nullable IRAlertAction *)cancelButtonAction
destructiveButtonAction:(nullable IRAlertAction *)destructiveButtonAction {
if(self = [super init]){
NSMutableArray<NSString *> * titles = [self titlesWithButtonActions:buttonActions];
alert = [[DEMOAlert alloc] initWithTitle:title message:message style:(DEMOAlertStyle)style buttonTitles:titles cancelButtonTitle:cancelButtonAction.title destructiveButtonTitle:destructiveButtonAction.title];
[self setupButtonActions:buttonActions cancelButtonAction:cancelButtonAction destructiveButtonAction:destructiveButtonAction];
[self registerForKeyboardNotifications];
}
return self;
}
IRAlert
methods-(void)setBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor;
-(void)setCornerRadius:(CGFloat)cornerRadius;
-(void)addAction:(IRAlertAction*)action;
IRAlertAction
work for DEMOAlert
, this is the most difficualt part, you need know how to use DEMOAlert
, and make DEMOAlert
call the handler of IRAlertAction
. In this example, DEMOAlert
has actionHandler
, cancelHandler
, and destructiveHandler
, and each handler is mapping to IRAlertAction
- (void)setupButtonActions:(NSArray<IRAlertAction *> * _Nullable)buttonActions cancelButtonAction:(IRAlertAction * _Nullable)cancelButtonAction destructiveButtonAction:(IRAlertAction * _Nullable)destructiveButtonAction {
__weak IRDEMOAlert* wself = self;
alert.actionHandler = ^(DEMOAlert * _Nonnull alertView, NSUInteger index, NSString * _Nullable title) {
if(index >= buttonActions.count)
return;
IRAlertAction *action = [buttonActions objectAtIndex:index];
action.handler(action);
};
alert.cancelHandler = ^(DEMOAlert * _Nonnull alertView) {
if (cancelButtonAction) {
cancelButtonAction.handler(cancelButtonAction);
}
};
alert.destructiveHandler = ^(DEMOAlert * _Nonnull alertView) {
if (destructiveButtonAction) {
destructiveButtonAction.handler(destructiveButtonAction);
}
};
}
IRAlertManager
.[[IRAlertManager sharedInstance] showAlert:alert];
[[IRAlertManager sharedInstance] hideAlert:alert];
IRAlertManager
.
[[IRAlertManager sharedInstance] showLoadingViewWithTarget:self backgroundImage:[ViewController imageWithColor:[UIColor greenColor] Size:[UIScreen mainScreen].bounds.size]];
[[IRAlertManager sharedInstance] hideLoadingViewWithTarget:self];
DEMOAlert
with loading view- (IBAction)showDEMOAlert:(id)sender {
IRAlertAction *commitAction = [[IRAlertAction alloc] init];
commitAction.title = @"OK";
commitAction.style = IRAlertActionStyleDefault;
IRAlertAction *cancelAction = [[IRAlertAction alloc] init];
cancelAction.title = @"Cancel";
cancelAction.style = IRAlertActionStyleCancel;
alert = [[IRDEMOAlert alloc] initWithTitle:nil message:nil style:IRDEMOAlertStyleAlert buttonActions:@[commitAction] cancelButtonAction:cancelAction destructiveButtonAction:nil];
__weak IRAlert *wAlert = alert;
commitAction.handler = ^(IRAlertAction * _Nonnull action) {
[[IRAlertManager sharedInstance] hideAlert:wAlert];
};
__weak ViewController *wSelf = self;
cancelAction.handler = ^(IRAlertAction * _Nonnull action) {
[[IRAlertManager sharedInstance] hideLoadingViewWithTarget:wSelf];
};
[alert setCornerRadius:20];
[[IRAlertManager sharedInstance] showAlert:alert];
}
Play | Seek |
---|---|
Volume | Brightness |
Full Screen | Lock Screen |
See IRPlayerUIShellViewController
for demo.
Create a IRPlayer instance.
self.playerImp = [IRPlayerImp player];
self.playerImp.decoder = [IRPlayerDecoder FFmpegDecoder];
[self.playerImp replaceVideoWithURL:VIDEO_URL];
self.player = [IRPlayerController playerWithPlayerManager:self.playerImp containerView:self.containerView];
self.player.controlView = self.controlView;
self.player.assetURLs = self.assetURLs;
self.player.pauseWhenAppResignActive = NO;
@weakify(self)
self.player.orientationWillChange = ^(IRPlayerController * _Nonnull player, BOOL isFullScreen) {
@strongify(self)
[self setNeedsStatusBarAppearanceUpdate];
};
self.player.playerDidToEnd = ^(id _Nonnull asset) {
@strongify(self)
[self.player.currentPlayerManager pause];
[self.player.currentPlayerManager play];
[self.player playTheNext];
if (!self.player.isLastAssetURL) {
NSString *title = [NSString stringWithFormat:@"title:%zd",self.player.currentPlayIndex];
[self.controlView showTitle:title coverURLString:kVideoCover fullScreenMode:IRFullScreenModeLandscape];
} else {
[self.player stop];
}
};
@import IRMusicPlayer;
MusicPlayerViewController *vc = [[MusicPlayerViewController alloc] initWithNibName:@"MusicPlayerViewController" bundle:xibBundle];
[vc.musicListArray addObject:@{@"musicAddress": [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"]}];
[vc.musicListArray addObject:@{@"musicAddress": [[NSBundle mainBundle] pathForResource:@"2" ofType:@"mp3"]}];
[vc.musicListArray addObject:@{@"musicAddress": [[NSBundle mainBundle] pathForResource:@"3" ofType:@"mp3"]}];
[self presentViewController:vc animated:YES completion:nil];
Demo Main Page | Camera |
---|---|
Camera with Grid View | Confirm |
Default filters | Album |
Custom filters | Update display view |
import IRUserResizableView_swift
...
override func viewDidLoad() {
super.viewDidLoad()
let appFrame = UIScreen.main.bounds
self.view = UIView.init(frame: appFrame);
self.view.backgroundColor = .green;
// (1) Create a user resizable view with a simple red background content view.
let gripFrame = CGRect.init(x: 50, y: 50, width: 200, height: 150)
let userResizableView = IRUserResizableView.init(frame: gripFrame)
let contentView = UIView.init(frame: gripFrame);
contentView.backgroundColor = .red;
userResizableView.contentView = contentView;
userResizableView.delegate = self;
userResizableView.showEditingHandles()
self.view.addSubview(userResizableView)
}
抽卡 | 集卡庫 | 排行榜 |
---|---|---|
5.5' | 6.5' |
---|---|
12.5' | 12.5' |
最新力作 海賊爭霸Online, 下載就送 S級火槍兵。 內建排行榜,集結軍團奪得最強海賊的頭銜吧!
感謝Android版作者AndyAWD先做出海賊爭霸Online,網址: https://play.google.com/store/apps/details?id=tw.com.andyawd.piratehegemonyonline
海賊爭霸Online GitHub iOS: https://github.com/irons163/PirateHegemonyOnline Android: https://github.com/AndyAWD/PirateHegemonyOnline
【臺灣400年系列電影】《臺灣三部曲》第一階段電影集資計畫 https://taiwantrilogy.com/
【大業配時代】流量就是一切!神秘廠商來襲!業配成功真相!feat.魏德聖 https://www.youtube.com/watch?v=LUaYe_7cmxQ
Demo1 | Demo2 |
---|---|
#import "TimelineManager.h"
...
Branch *branch = [[TimelineManager sharedInstance] branchFromClientJourneyData:_clientJourneyData];
branch.tableView = self.timelineTableView;
branch.delegate = self;
[self.timelineTableView reloadDataWithCompletion:^{
[self.delegate didUpdate:nil];
}];
#import "TimelineManager.h"
...
@interface MonitorClientsDetailTimelineTableViewCell ()<BranchDelegate>
...
- (void)willUpdate:(NSNumber *)pos {
[self.delegate willUpdate:pos];
}
- (void)didUpdate:(NSNumber *)pos {
[self layoutIfNeeded];
[self.delegate didUpdate:pos];
}
Share Extension | Files List |
---|---|
Demo Main Page | Demo1 |
---|---|
IRHTTPCache is a copy project from KTVHTTPCache.
A usage case is using IRHTTPCache combine with the video player(IRPlayer) for cache.
demo
and ScreenShots
folder.pod 'IRHTTPCache'
in the Podfile
pod install
[IRHTTPCache proxyStart:&error];
NSURL *proxyURL = [IRHTTPCache proxyURLWithOriginalURL:originalURL];
AVPlayer *player = [AVPlayer playerWithURL:proxyURL];
NSURL *completeCacheFileURL= [IRHTTPCache cacheCompleteFileURLWithURL:originalURL];
[IRHTTPCache encodeSetURLConverter:^NSURL *(NSURL *URL) {
return URL;
}];
// Timeout interval.
[IRHTTPCache downloadSetTimeoutInterval:30];
// Accept Content-Type.
[IRHTTPCache downloadSetAcceptableContentTypes:contentTypes];
// Set unsupport Content-Type filter.
[IRHTTPCache downloadSetUnacceptableContentTypeDisposer:^BOOL(NSURL *URL, NSString *contentType) {
return NO;
}];
// Additional headers.
[IRHTTPCache downloadSetAdditionalHeaders:headers];
// Whitelist headers.
[IRHTTPCache downloadSetWhitelistHeaderKeys:headers];
// Console.
[IRHTTPCache logSetConsoleLogEnable:YES];
// File.
[IRHTTPCache logSetRecordLogEnable:YES];
NSString *logFilePath = [IRHTTPCache logRecordLogFilePath];
Demo1 | Demo2 |
---|---|
This project is nice to cooperate with IRGallery. See demo to learn how to use it.
IRImagePickerController *imagePickerController = [IRImagePickerController new];
imagePickerController.delegate = self;
imagePickerController.allowsMultipleSelection = YES;
imagePickerController.maximumNumberOfSelection = 6;
imagePickerController.showsNumberOfSelectedAssets = YES;
[self presentViewController:imagePickerController animated:YES completion:NULL];
Display | Setting |
---|---|
OldPodcasts
cannot not work, so if you like OldPodcasts
, please feel free to use this one IRPodcast
.Codable
.Demo1 | Demo2 |
---|---|
Demo3 | |
reuseIdentifier
to every items in the collection view.NSString *identifier = [NSString stringWithFormat:@"Identifier_%d-%d-%d", (int)indexPath.section, (int)indexPath.row, (int)indexPath.item];
[collectionView registerNib:[UINib nibWithNibName:CollectionViewCell.identifier bundle:nil] forCellWithReuseIdentifier:identifier];
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
Demo1 | Demo2 |
---|---|
Class
amd Utility
folders into your own project.README
or ViewController.m
.#import "TimelineManager.h"
...
Branch *branch = [[TimelineManager sharedInstance] branchFromClientJourneyData:_clientJourneyData];
branch.tableView = self.timelineTableView;
branch.delegate = self;
[self.timelineTableView reloadDataWithCompletion:^{
[self.delegate didUpdate:nil];
}];
#import "TimelineManager.h"
...
@interface MonitorClientsDetailTimelineTableViewCell ()<BranchDelegate>
...
- (void)willUpdate:(NSNumber *)pos {
[self.delegate willUpdate:pos];
}
- (void)didUpdate:(NSNumber *)pos {
[self layoutIfNeeded];
[self.delegate didUpdate:pos];
}
Demo | Passcode Settings |
---|---|
Set Passcode | Confirm Passcode |
Confirm Passcode Fail | Change Passcode |
Unlock Passcode | Demo Private Data |
demo
and ScreenShots
folder.pod 'IRPasscode'
in the Podfile
pod install
Passcode Setting Page
.#import <IRPasscode/IRPasscode.h>
NSBundle *xibBundle = [NSBundle bundleForClass:[IRPasscodeLockSettingViewController class]];
IRPasscodeLockSettingViewController *vc = [[IRPasscodeLockSettingViewController alloc] initWithNibName:@"IRPasscodeLockSettingViewController" bundle:xibBundle];
[self.navigationController pushViewController:vc animated:YES];
Passcode verify page
.if ([IRSecurityPinManager sharedInstance].pinCode)
[[IRSecurityPinManager sharedInstance] presentSecurityPinViewControllerForUnlockWithAnimated:YES completion:nil result:nil];
Stickers | After effections |
---|---|
demo
and ScreenShots
folder.pod 'IRSticker'
in the Podfile
pod install
pod 'IRSingleButtonGroup-swift'
in the Podfile
pod install
pod 'IRSingleButtonGroup'
in the Podfile
pod install
IRSingleButtonGroup* singleButtonGroup = [[IRSingleButtonGroup alloc] init];
singleButtonGroup.buttons = @[self.button1, self.button2, self.button3];
singleButtonGroup.delegate = self;
#pragma mark - SingleButtonGroupDelegate
- (void)didSelectedButton:(UIButton *)button {
NSLog(@"Button%ld", button.tag);
}
- (void)didDeselectedButton:(UIButton *)button {
NSLog(@"Button%ld", button.tag);
}