summaryrefslogtreecommitdiff
path: root/ios/iosremote
diff options
context:
space:
mode:
authorsiqi <me@siqi.fr>2013-07-08 01:12:39 +0200
committersiqi <me@siqi.fr>2013-07-08 01:13:03 +0200
commita2fc3ecb15c7def2016d0495e797239fb7ef132b (patch)
tree23fa9417a7a104212133694a7ad465907fba2b2c /ios/iosremote
parentb7072fcea570f8ceed30a743d9d0d66a5e4bc549 (diff)
loads slides & notes async, queue multiple slides and reload when received
Change-Id: Iace2f120b70df02ddb004b9f67cb8b548b9277d8
Diffstat (limited to 'ios/iosremote')
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.pbxproj4
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstatebin29283 -> 33638 bytes
-rw-r--r--ios/iosremote/iosremote/Communication/SlideShow.h3
-rw-r--r--ios/iosremote/iosremote/Communication/SlideShow.m96
-rw-r--r--ios/iosremote/iosremote/slideShowPreviewTable_vc.m1
-rw-r--r--ios/iosremote/iosremote/slideShow_vc146
-rw-r--r--ios/iosremote/iosremote/slideShow_vc.m25
-rw-r--r--ios/iosremote/iosremote/slide_finished.pngbin0 -> 11049 bytes
8 files changed, 221 insertions, 54 deletions
diff --git a/ios/iosremote/iosremote.xcodeproj/project.pbxproj b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
index ebbd706a5ac2..962ddd52c098 100644
--- a/ios/iosremote/iosremote.xcodeproj/project.pbxproj
+++ b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
@@ -18,6 +18,7 @@
57AEEDAD1789543D007F4F97 /* libO_toolBar_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 57AEEDAC1789543D007F4F97 /* libO_toolBar_bg.png */; };
57AEEDAF17895B67007F4F97 /* pointer.png in Resources */ = {isa = PBXBuildFile; fileRef = 57AEEDAE17895B67007F4F97 /* pointer.png */; };
57AEEDB117895BF5007F4F97 /* pointer_pushed.png in Resources */ = {isa = PBXBuildFile; fileRef = 57AEEDB017895BF5007F4F97 /* pointer_pushed.png */; };
+ 57AEEDB517899BB4007F4F97 /* slide_finished.png in Resources */ = {isa = PBXBuildFile; fileRef = 57AEEDB417899BB4007F4F97 /* slide_finished.png */; };
57B152991764703500EECC67 /* Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B152981764703500EECC67 /* Base64.m */; };
57B1529F176486C300EECC67 /* CommandTransmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B1529E176486C300EECC67 /* CommandTransmitter.m */; };
57B7625D17621E42007703F6 /* SlideShow.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B7625C17621E42007703F6 /* SlideShow.m */; };
@@ -57,6 +58,7 @@
57AEEDAC1789543D007F4F97 /* libO_toolBar_bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = libO_toolBar_bg.png; path = iosremote/libO_toolBar_bg.png; sourceTree = "<group>"; };
57AEEDAE17895B67007F4F97 /* pointer.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pointer.png; path = iosremote/pointer.png; sourceTree = "<group>"; };
57AEEDB017895BF5007F4F97 /* pointer_pushed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pointer_pushed.png; path = iosremote/pointer_pushed.png; sourceTree = "<group>"; };
+ 57AEEDB417899BB4007F4F97 /* slide_finished.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = slide_finished.png; path = iosremote/slide_finished.png; sourceTree = "<group>"; };
57B152971764703500EECC67 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
57B152981764703500EECC67 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = "<group>"; };
57B1529D176486C300EECC67 /* CommandTransmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommandTransmitter.h; sourceTree = "<group>"; };
@@ -114,6 +116,7 @@
57AEEDAA1788D7B2007F4F97 /* Assets */ = {
isa = PBXGroup;
children = (
+ 57AEEDB417899BB4007F4F97 /* slide_finished.png */,
57AEEDB017895BF5007F4F97 /* pointer_pushed.png */,
57AEEDAE17895B67007F4F97 /* pointer.png */,
57AEEDAC1789543D007F4F97 /* libO_toolBar_bg.png */,
@@ -290,6 +293,7 @@
57AEEDAD1789543D007F4F97 /* libO_toolBar_bg.png in Resources */,
57AEEDAF17895B67007F4F97 /* pointer.png in Resources */,
57AEEDB117895BF5007F4F97 /* pointer_pushed.png in Resources */,
+ 57AEEDB517899BB4007F4F97 /* slide_finished.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
index f0a68c834010..bdc9bb5cf87c 100644
--- a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
+++ b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
Binary files differ
diff --git a/ios/iosremote/iosremote/Communication/SlideShow.h b/ios/iosremote/iosremote/Communication/SlideShow.h
index e49ba3f9e42d..52d699a9263a 100644
--- a/ios/iosremote/iosremote/Communication/SlideShow.h
+++ b/ios/iosremote/iosremote/Communication/SlideShow.h
@@ -20,7 +20,6 @@
- (void) putImage: (NSString *)img AtIndex: (uint) index;
- (void) putNotes: (NSString *)notes AtIndex: (uint) index;
-- (UIImage *) getImageAtIndex: (uint) index;
-- (NSString *) getNotesAtIndex: (uint) index;
+- (void) getContentAtIndex: (uint) index forView: (UIView*) view;
@end
diff --git a/ios/iosremote/iosremote/Communication/SlideShow.m b/ios/iosremote/iosremote/Communication/SlideShow.m
index b2d6016da33f..43b80be362b2 100644
--- a/ios/iosremote/iosremote/Communication/SlideShow.m
+++ b/ios/iosremote/iosremote/Communication/SlideShow.m
@@ -17,7 +17,7 @@
@property (nonatomic, strong) NSMutableDictionary* imagesDictionary;
@property (nonatomic, strong) NSMutableDictionary* notesDictionary;
-@property int lastRequestedImage, lastRequestedNote;
+@property (nonatomic, strong) NSMutableDictionary* loadBuffer;
@property (nonatomic, strong) id slideShowImageReadyObserver;
@property (nonatomic, strong) id slideShowNoteReadyObserver;
@@ -35,84 +35,92 @@ dispatch_queue_t backgroundQueue;
self = [super init];
self.imagesDictionary = [[NSMutableDictionary alloc] init];
self.notesDictionary = [[NSMutableDictionary alloc] init];
+ self.loadBuffer = [[NSMutableDictionary alloc] init];
_size = 0;
_currentSlide = 0;
- self.lastRequestedImage = -1;
- self.lastRequestedNote = -1;
backgroundQueue = dispatch_queue_create("org.libreoffice.iosremote.bgqueue", NULL);
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+ /**
+ This observer waits for storage updates like new image added or notes received.
+ It then checks in the loadBuffer to see if there is a view waiting for this update in loadBuffer, if yes, it loads it up and remove the waiting entry.
+ loadBuffer stores key-value pair with viewTag as a key and slideIndex as value.
+ For the same view, we only keep the last requested slide index on the waiting list.
+ It is thus indispensable to identify each view with an unique tag in its view controller. Here we use 0-10 to indentify central vc views and 11-N for swipe-in tableViewController which allows direct slide number change.
+ We handle lecturer's notes at the same time as an entry in the load buffer via an instrospection.
+ */
self.slideShowImageReadyObserver =[[NSNotificationCenter defaultCenter]
- addObserverForName:@"storage_update_image_ready"
+ addObserverForName:@"storage_update_ready"
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
- if ([[[note userInfo] objectForKey:@"index"] intValue] == self.lastRequestedImage) {
- NSLog(@"Load last requsted image: %u", self.lastRequestedImage);
- [[self.delegate slideView] setImage:[self getImageAtIndex:self.lastRequestedImage]];
- self.lastRequestedImage = -1;
+ if ([[self.loadBuffer allKeysForObject:[NSNumber numberWithInt:[[[note userInfo] objectForKey:@"index"] intValue]]] count]) {
+ NSArray * tagArray = [self.loadBuffer allKeysForObject:[NSNumber numberWithInt:[[[note userInfo] objectForKey:@"index"] intValue]]];
+ for (NSNumber *tag in tagArray) {
+ UIView * view = [[self.delegate view] viewWithTag:[tag integerValue]];
+ if ([view isKindOfClass:[UIImageView class]]){
+ UIImage *image = [self.imagesDictionary objectForKey:[self.loadBuffer objectForKey:tag]];
+ if (image) {
+ [(UIImageView *)view setImage:image];
+ [self.loadBuffer removeObjectForKey:tag];
+ }
+ }
+ else if ([view isKindOfClass:[UIWebView class]]){
+ NSLog(@"Async notes");
+ NSString *note = [self.notesDictionary objectForKey:[self.loadBuffer objectForKey:tag]];
+ if (note) {
+ [(UIWebView *)view loadHTMLString:note baseURL:nil];
+ [self.loadBuffer removeObjectForKey:tag];
+ }
+ }
+
+ }
}
}];
-
- self.slideShowNoteReadyObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"storage_update_note_ready"
- object:nil
- queue:mainQueue
- usingBlock:^(NSNotification *note) {
-// NSLog(@"Load last requsted note");
- if ([[[note userInfo] objectForKey:@"index"] intValue] == self.lastRequestedNote) {
- [[self.delegate lecturer_notes] loadHTMLString:[self getNotesAtIndex:self.lastRequestedNote] baseURL:nil];
- self.lastRequestedNote = -1;
- }
- }];
-
return self;
}
- (void) putImage: (NSString *)img AtIndex: (uint) index{
// NSLog(@"Put Image into %u", index);
- dispatch_async(backgroundQueue, ^(void) {
NSData* data = [NSData dataWithBase64String:img];
UIImage* image = [UIImage imageWithData:data];
+ NSLog(@"%@", image);
[self.imagesDictionary setObject:image forKey:[NSNumber numberWithUnsignedInt:index]];
- [[NSNotificationCenter defaultCenter] postNotificationName:@"storage_update_image_ready"
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"storage_update_ready"
object:nil
userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:index] forKey:@"index"]];
- });
+
}
- (void) putNotes: (NSString *)notes AtIndex: (uint) index{
// NSLog(@"Put note into %u", index);
[self.notesDictionary setObject:notes forKey:[NSNumber numberWithUnsignedInt:index]];
- [[NSNotificationCenter defaultCenter] postNotificationName:@"storage_update_note_ready"
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"storage_update_ready"
object:nil
userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:index] forKey:@"index"]];
}
-- (UIImage *) getImageAtIndex: (uint) index
+- (void) getContentAtIndex: (uint) index forView: (UIView*) view
{
- if (![self.imagesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]]) {
- self.lastRequestedImage = index;
- return nil;
+ if (index >= self.size)
+ {
+ if ([view isKindOfClass:[UIImageView class]])
+ [(UIImageView* )view setImage:[UIImage imageNamed:@"slide_finished.png"]];
+ else if ([view isKindOfClass:[UIWebView class]])
+ [(UIWebView* )view loadHTMLString: @"SlideShow finished" baseURL:nil];
+ return;
}
- else{
- self.lastRequestedImage = -1;
- return [self.imagesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]];
- }
-}
-
-- (NSString *) getNotesAtIndex: (uint) index
-{
- if (![self.notesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]]) {
- self.lastRequestedNote = index;
- return nil;
+ if (![self.imagesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]])
+ {
+ [self.loadBuffer setObject:[NSNumber numberWithInt:index ] forKey:[NSNumber numberWithInt:[view tag]]];
}
- else {
- self.lastRequestedNote = -1;
- return [self.notesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]];
+ else{
+ if ([view isKindOfClass:[UIImageView class]])
+ [(UIImageView* )view setImage:[self.imagesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]]];
+ else if ([view isKindOfClass:[UIWebView class]])
+ [(UIWebView* )view loadHTMLString: [self.notesDictionary objectForKey:[NSNumber numberWithUnsignedInt:index]] baseURL:nil];
}
}
-
-
@end
diff --git a/ios/iosremote/iosremote/slideShowPreviewTable_vc.m b/ios/iosremote/iosremote/slideShowPreviewTable_vc.m
index 1ab6b1a517bd..df8f093c8102 100644
--- a/ios/iosremote/iosremote/slideShowPreviewTable_vc.m
+++ b/ios/iosremote/iosremote/slideShowPreviewTable_vc.m
@@ -55,7 +55,6 @@
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
- NSLog(@"Setting to true");
self.slidesRunning = YES;
}];
diff --git a/ios/iosremote/iosremote/slideShow_vc b/ios/iosremote/iosremote/slideShow_vc
new file mode 100644
index 000000000000..3fc86167d1d6
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShow_vc
@@ -0,0 +1,146 @@
+/
+// slideShow_vc.m
+// iosremote
+//
+// Created by Liu Siqi on 7/5/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "slideShow_vc.h"
+#import "SlideShow.h"
+#import "CommunicationManager.h"
+#import "CommandInterpreter.h"
+#import "CommandTransmitter.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+#define CURRENT_SLIDE_IMAGEVIEW 1
+#define NEXT_SLIDE_IMAGEVIEW 2
+#define CURRENT_SLIDE_NOTES 2
+
+@interface slideShow_vc ()
+
+@property (nonatomic, strong) CommunicationManager *comManager;
+@property (nonatomic, strong) id slideShowImageNoteReadyObserver;
+@property (nonatomic, strong) id slideShowFinishedObserver;
+@property (nonatomic, strong) SlideShow* slideshow;
+
+@end
+
+@implementation slideShow_vc
+
+@synthesize comManager = _comManager;
+@synthesize slideShowImageNoteReadyObserver = _slideShowImageNoteReadyObserver;
+@synthesize slideShowFinishedObserver = _slideShowFinishedObserver;
+@synthesize slideshow = _slideshow;
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ self.comManager = [CommunicationManager sharedComManager];
+ self.slideshow = [self.comManager.interpreter slideShow];
+ self.slideshow.delegate = self;
+
+ [self.slideView setImage:[self.slideshow getImageAtIndex:self.slideshow.currentSlide]];
+ [self.lecturer_notes loadHTMLString: [self.slideshow getNotesAtIndex:self.slideshow.currentSlide]baseURL:nil];
+ [self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
+
+ UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"End"
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(handleBack:)];
+ self.navigationItem.leftBarButtonItem = backButton;
+}
+
+- (void) handleBack:(id)sender
+{
+ [self.comManager.transmitter stopPresentation];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+
+ self.slideShowImageNoteReadyObserver =[center addObserverForName:MSG_SLIDE_CHANGED
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ NSLog(@"Getting slide: %u image to display: %@", self.slideshow.currentSlide, [self.slideshow getImageAtIndex:self.slideshow.currentSlide]);
+
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.slideshow];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.lecturer_notes];
+
+ [self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
+
+ }];
+
+ self.slideShowFinishedObserver = [center addObserverForName:STATUS_CONNECTED_NOSLIDESHOW
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ [self.navigationController popViewControllerAnimated:YES];
+ }];
+ self.slideView.layer.shadowColor = [[UIColor blackColor] CGColor];
+ self.slideView.layer.shadowOpacity = 0.5;
+ self.slideView.layer.shadowRadius = 4.0;
+ self.slideView.layer.shadowOffset = CGSizeMake(3.0f, 3.0f);
+ self.slideView.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.slideView.bounds].CGPath;
+ self.slideView.clipsToBounds = NO;
+
+ self.secondarySlideView.layer.shadowColor = [[UIColor blackColor] CGColor];
+ self.secondarySlideView.layer.shadowOpacity = 0.5;
+ self.secondarySlideView.layer.shadowRadius = 4.0;
+ self.secondarySlideView.layer.shadowOffset = CGSizeMake(3.0f, 3.0f);
+ self.secondarySlideView.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.secondarySlideView.bounds].CGPath;
+ self.secondarySlideView.clipsToBounds = NO;
+
+ [super viewDidAppear:animated];
+}
+
+- (void) viewDidDisappear:(BOOL)animated
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self.slideShowFinishedObserver];
+ [[NSNotificationCenter defaultCenter] removeObserver:self.slideShowImageNoteReadyObserver];
+ [super viewDidDisappear:animated];
+}
+
+
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void)viewDidUnload {
+ [self setLecturer_notes:nil];
+ [self setSlideView:nil];
+ [self setSlideNumber:nil];
+ [self setSecondarySlideView:nil];
+ [self setNotesView:nil];
+ [super viewDidUnload];
+}
+
+- (IBAction)nextSlideAction:(id)sender {
+ [[self.comManager transmitter] nextTransition];
+}
+
+- (IBAction)previousSlideAction:(id)sender {
+ [[self.comManager transmitter] previousTransition];
+}
+
+- (IBAction)pointerAction:(id)sender {
+}
+@end
diff --git a/ios/iosremote/iosremote/slideShow_vc.m b/ios/iosremote/iosremote/slideShow_vc.m
index b4888293dd02..df5fb5eb56e0 100644
--- a/ios/iosremote/iosremote/slideShow_vc.m
+++ b/ios/iosremote/iosremote/slideShow_vc.m
@@ -13,6 +13,11 @@
#import "CommandTransmitter.h"
#import <QuartzCore/QuartzCore.h>
+
+#define CURRENT_SLIDE_IMAGEVIEW 1
+#define NEXT_SLIDE_IMAGEVIEW 2
+#define CURRENT_SLIDE_NOTES 3
+
@interface slideShow_vc ()
@property (nonatomic, strong) CommunicationManager *comManager;
@@ -41,14 +46,22 @@
- (void)viewDidLoad
{
[super viewDidLoad];
+
+ // Unique tag assignment. Don't use 0 as it's default. 0-10 for central VC
+ [self.slideView setTag:CURRENT_SLIDE_IMAGEVIEW];
+ [self.secondarySlideView setTag:NEXT_SLIDE_IMAGEVIEW];
+ [self.lecturer_notes setTag:CURRENT_SLIDE_NOTES];
+
self.comManager = [CommunicationManager sharedComManager];
self.slideshow = [self.comManager.interpreter slideShow];
self.slideshow.delegate = self;
- [self.slideView setImage:[self.slideshow getImageAtIndex:self.slideshow.currentSlide]];
- [self.lecturer_notes loadHTMLString: [self.slideshow getNotesAtIndex:self.slideshow.currentSlide]baseURL:nil];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.slideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide+1 forView:self.secondarySlideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.lecturer_notes];
[self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
+
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"End"
style:UIBarButtonItemStyleBordered
target:self
@@ -72,11 +85,9 @@
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
- NSLog(@"Getting slide: %u image to display: %@", self.slideshow.currentSlide, [self.slideshow getImageAtIndex:self.slideshow.currentSlide]);
-
- [self.slideView setImage:[self.slideshow getImageAtIndex:self.slideshow.currentSlide]];
- [self.lecturer_notes loadHTMLString: [self.slideshow getNotesAtIndex:self.slideshow.currentSlide]baseURL:nil];
-
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.slideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide+1 forView:self.secondarySlideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.lecturer_notes];
[self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
}];
diff --git a/ios/iosremote/iosremote/slide_finished.png b/ios/iosremote/iosremote/slide_finished.png
new file mode 100644
index 000000000000..8f57eaa6169a
--- /dev/null
+++ b/ios/iosremote/iosremote/slide_finished.png
Binary files differ