Page View Controller: UILabel and UIImageview empty on first page - uilabel

I'm using a UIPageViewController to display items from a JSON file. It works fine except for the first page which displays nothing on loading, but if I come back, it works.
Code is as follows:
#import "SJPagesViewController.h"
#import "SJChildViewController.h"
#interface SJPagesViewController ()
#end
#implementation SJPagesViewController
#synthesize urlToFollow, data,articlesArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
...
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
CGFloat window_height = ([self window_height]-30.0);
CGFloat window_width = [self window_width];
CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);
self.pageController.dataSource = self;
[[self.pageController view] setFrame:pageFrame];
SJChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
//Download JSON
NSError *error=nil;
NSURL *url = [NSURL URLWithString:urlToFollow];
data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *response = [dictionary objectForKey:#"items"];
articlesArray = [[NSArray alloc] initWithArray:response];
//NSLog(#"articlesArray = %#", articlesArray);
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [(SJChildViewController *)viewController index];
if (index == 0) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(SJChildViewController *)viewController index];
index++;
if (index == articlesArray.count) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (CGFloat) window_height {
return [UIScreen mainScreen].applicationFrame.size.height;
}
- (CGFloat) window_width {
return [UIScreen mainScreen].applicationFrame.size.width;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (SJChildViewController *)viewControllerAtIndex:(NSUInteger)index {
SJChildViewController *childViewController = [[SJChildViewController alloc] initWithNibName:#"SJChildViewController" bundle:nil];
childViewController.index = index;
childViewController.arrayCount = self.articlesArray.count;
childViewController.model = [[self.articlesArray objectAtIndex:index]objectForKey:#"modelo"];
childViewController.price = [[self.articlesArray objectAtIndex:index]objectForKey:#"precio"];
childViewController.make = [[self.articlesArray objectAtIndex:index]objectForKey:#"marca"];
childViewController.imageUrl = [[self.articlesArray objectAtIndex:index]objectForKey:#"photoUrl"];
return childViewController;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
if (articlesArray.count >5) {
return 5;
}else return [articlesArray count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
#end
And ChildViewController to display items:
#implementation SJChildViewController
#synthesize activityIndicator,imageUrl,price,model,make;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
....
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Activity indicator
activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
}
-(void)viewDidAppear:(BOOL)animated{
self.scrrenNumber.text = [NSString stringWithFormat:#"Artículo %ld de %ld", ((long)self.index+1), (long)self.arrayCount];
self.lblMake.lineBreakMode = NSLineBreakByWordWrapping;
self.lblMake.text = [NSString stringWithFormat:#"%#",make];
//Donload image
//Download image from url
NSURL *url_1= [NSURL URLWithString:imageUrl];
NSURLRequest *request_1 = [NSURLRequest requestWithURL:url_1];
[NSURLConnection sendAsynchronousRequest:request_1
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
UIImage *img = [UIImage imageWithData:data];
[self.articleImage performSelectorOnMainThread:#selector(setImage:) withObject:img waitUntilDone:YES];
}];
//Activity indicator
self.lblPrice.text = [NSString stringWithFormat:#"%#",price];
self.lblModel.lineBreakMode = NSLineBreakByWordWrapping;
self.lblModel.text = [NSString stringWithFormat:#"%#",model];
[activityIndicator stopAnimating];
}
How can I make it work from the first moment?

Luis, I don't have access to xcode right now but it appears your issue is that you are instantiating childViewController while articlesArray is empty.
In viewDidLoad you are downloading your json file and populating articlesArray after you call your helper method viewControllerAtIndex.
Try downloading your json file and populating the array first like you have here.
//Download JSON
NSError *error=nil;
NSURL *url = [NSURL URLWithString:urlToFollow];
data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *response = [dictionary objectForKey:#"items"];
articlesArray = [[NSArray alloc] initWithArray:response];
Then create your pageViewController and populate it like you did here.
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
CGFloat window_height = ([self window_height]-30.0);
CGFloat window_width = [self window_width];
CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);
self.pageController.dataSource = self;
[[self.pageController view] setFrame:pageFrame];
SJChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];

Related

Which third party Imageview class should i used?

My requirement is :
Need to show image in imageview from server URL & save it for offline use also.
But There may be chances that same URL image can be updated.
I tried EGOImageview,AsyncImageview,FXImageview,Haneke thsese all classes i tried.
my first part of requirement is achieved. but not second..i.e if "xxxxx" link image is shown for first time....if on that same link image is upadated ,app shows old image only...
You can use the below class that will full fill your requirement
DImageView.h
#import <UIKit/UIKit.h>
#interface DImageView : UIImageView
#property (nonatomic, strong) UIActivityIndicatorView *activityView;
- (void)processImageDataWithURLString:(NSString *)urlString;
+ (UIImage *)getSavedImage :(NSString *)fileName;
+ (void)saveImageWithFolderName:(NSString *)folderName AndFileName:(NSString *)fileName AndImage:(NSData *) imageData;
DImageView.m
#import "DImageView.h"
#define IMAGES_FOLDER_NAME #"DImages"
#implementation DImageView
#pragma mark - App Life Cycle
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
- (void)dealloc
{
self.activityView = nil;
[super dealloc];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self initWithFrame:[self frame]];
}
return self;
}
#pragma mark - Download images
- (void)processImageDataWithURLString:(NSString *)urlString //andBlock:(void (^)(UIImage * img))processImage
{
#autoreleasepool
{
UIImage * saveImg = [DImageView getSavedImage:urlString];
if (saveImg)
{
dispatch_queue_t callerQueue = dispatch_get_main_queue();
dispatch_async(callerQueue, ^{
#autoreleasepool
{
[self setImage:saveImg];
}
});
}
else
{
[self showActivityIndicator];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
dispatch_queue_t callerQueue = dispatch_get_main_queue();
dispatch_queue_t downloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
__block NSError* error = nil;
dispatch_async(downloadQueue, ^{
NSData * imageData = [[[NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&error] retain] autorelease];
if (error)
{
NSLog(#"DImg Error %#", [error debugDescription]);
}
else
{
dispatch_async(callerQueue, ^{
#autoreleasepool
{
UIImage *image = [UIImage imageWithData:imageData];
[self setImage:image];
[self hideActivityIndicator];
/* Below code is to save image*/
[DImageView saveImageWithFolderName:IMAGES_FOLDER_NAME AndFileName:urlString AndImage:imageData];
}
});
}
});
dispatch_release(downloadQueue);
}
}
}
#pragma mark - File Save methods
+ (void)saveImageWithFolderName:(NSString *)folderName AndFileName:(NSString *)fileName AndImage:(NSData *) imageData
{
#autoreleasepool
{
NSFileManager *fileManger = [NSFileManager defaultManager] ;
NSString *directoryPath = [NSString stringWithFormat:#"%#/%#",[DImageView applicationDocumentsDirectory],folderName] ;
if (![fileManger fileExistsAtPath:directoryPath])
{
NSError *error = nil;
[fileManger createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&error];
}
fileName = [DImageView fileNameValidate:fileName];
NSString *filePath = [NSString stringWithFormat:#"%#/%#",directoryPath,fileName] ;
BOOL isSaved = [imageData writeToFile:filePath atomically:YES];
if (!isSaved)
{
NSLog(#" ** Img Not Saved");
}
}
}
+ (NSString *)applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
+ (UIImage *)getSavedImage :(NSString *)fileName
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
fileName = [DImageView fileNameValidate:fileName];
NSFileManager * fileManger = [NSFileManager defaultManager] ;
NSString * directoryPath = [NSString stringWithFormat:#"%#/%#",[DImageView applicationDocumentsDirectory],IMAGES_FOLDER_NAME] ;
NSString * filePath = [NSString stringWithFormat:#"%#/%#",directoryPath,fileName] ;
if ([fileManger fileExistsAtPath:directoryPath])
{
UIImage *image = [UIImage imageWithContentsOfFile:filePath] ;
if (image)
{
return image;
}
else
{
NSLog(#"** Img Not Found **");
return nil;
}
}
[pool release];
return nil;
}
+ (NSString*) fileNameValidate : (NSString*) name
{
name = [name stringByReplacingOccurrencesOfString:#"://" withString:#"##"];
name = [name stringByReplacingOccurrencesOfString:#"/" withString:#"#"];
name = [name stringByReplacingOccurrencesOfString:#"%20" withString:#""];
return name;
}
#pragma mark - Activity Methods
- (void) showActivityIndicator
{
self.activityView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
self.activityView.hidesWhenStopped = TRUE;
self.activityView.backgroundColor = [UIColor clearColor];
self.activityView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[self addSubview:self.activityView];
[self.activityView startAnimating];
}
- (void) hideActivityIndicator
{
CAAnimation *animation = [NSClassFromString(#"CATransition") animation];
[animation setValue:#"kCATransitionFade" forKey:#"type"];
animation.duration = 0.4;;
[self.layer addAnimation:animation forKey:nil];
[self.activityView stopAnimating];
[self.activityView removeFromSuperview];
for (UIView * view in self.subviews)
{
if([view isKindOfClass:[UIActivityIndicatorView class]])
[view removeFromSuperview];
}
}
What will this class do ?
It will download images from server and save it to application document directory And get it from local if its available.
How to use that ?
Set DImageView class in your nib file for UIImageView.
Then you can simply use it as below in your .m file.
[imgViewName processImageDataWithURLString:imageURl];
You should take a look at SDWebImage. It's one of the most used UIImageView category right now and offers a lot of features, including caching.
Have a look at this part of the documentation to learn how to refresh your cache with it: Handle image refresh

Unable to call up my video files using AVFoundation

I'm having difficulty playing back video that I've recently recorded in a hybrid image/video camera akin to Snapchat (e.g. tap to take a photo, press and hold to record a video, playback on button release).
I'm currently saving the video file to NSFileManager. When I log it out I do verify that something is being saved but can't inspect the file because it has to be tested on the phone.
The file path when I log it out:
file:///var/mobile/Containers/Data/Application/7D86B14D-ACFF-4494-AD61-CBBD32DCA7A5/Documents/test.mov
When I go to load the asset from the file manager I log out an error that it can't open the files. I've only just started working with AVFoundation so not sure what some of the issues/considerations are when debugging. Any insight would be greatly appreciated, thank you!
Referenced tutorial
Referenced github repository
Referenced code:
PlayerView.h (reference)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface PlayerView : UIView
#property (nonatomic) AVPlayer *player;
- (void)setPlayer:(AVPlayer *)player;
#end
PlayerView.m (reference)
#import "PlayerView.h"
#implementation PlayerView
+ (Class)layerClass {
return [AVPlayerLayer class];
}
- (AVPlayer *)player {
return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
}
#end
HybridCameraViewController.h (reference)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "PlayerView.h"
#interface HybridCameraViewController : UIViewController
#property UIButton *button;
#property UIButton *saveButton;
#property UIImageView *previewView;
#define VIDEO_FILE #"test.mov"
#end
HybridCameraViewController.m (reference)
#import "HybridCameraViewController.h"
static const NSString *ItemStatusContext;
#class PlayerView;
#interface HybridCameraViewController () <AVCaptureFileOutputRecordingDelegate>
#end
#implementation HybridCameraViewController
AVCaptureSession *session;
AVCaptureStillImageOutput *imageOutput;
AVCaptureMovieFileOutput *movieOutput;
AVCaptureConnection *videoConnection;
AVPlayer *player;
AVPlayerItem *playerItem;
PlayerView *playerView;
- (void)viewDidLoad {
[super viewDidLoad];
[self testDevices];
self.view.backgroundColor = [UIColor blackColor];
//Image preview
self.previewView = [[UIImageView alloc]initWithFrame:self.view.frame];
self.previewView.backgroundColor = [UIColor whiteColor];
self.previewView.contentMode = UIViewContentModeScaleAspectFill;
self.previewView.hidden = YES;
[self.view addSubview:self.previewView];
//Playerback setup
playerView = [[PlayerView alloc]initWithFrame:self.view.frame];
playerView.backgroundColor = [UIColor redColor];
[self syncUI];
//Buttons
self.button = [self createButtonWithTitle:#"REC" chooseColor:[UIColor redColor]];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.button addGestureRecognizer:longPressRecognizer];
[self.button addTarget:self action:#selector(captureImage) forControlEvents:UIControlEventTouchUpInside];
self.saveButton = [self createSaveButton];
[self.saveButton addTarget:self action:#selector(saveActions) forControlEvents:UIControlEventTouchUpInside];
}
- (void)viewWillAppear:(BOOL)animated {
//Tests
[self initializeAVItems];
NSLog(#"%#", videoConnection);
NSLog(#"%#", imageOutput.connections);
NSLog(#"%#", imageOutput.description.debugDescription);
}
#pragma mark - AV initialization
- (void)initializeAVItems {
//Start session, input
session = [AVCaptureSession new];
if ([session canSetSessionPreset:AVCaptureSessionPresetHigh]) {
session.sessionPreset = AVCaptureSessionPresetHigh;
}
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
if ([session canAddInput:deviceInput]) {
[session addInput:deviceInput];
} else {
NSLog(#"%#", error);
}
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//Layer preview
CALayer *viewLayer = [[self view] layer];
[viewLayer setMasksToBounds:YES];
CGRect frame = self.view.frame;
[previewLayer setFrame:frame];
[viewLayer insertSublayer:previewLayer atIndex:0];
//Image Output
imageOutput = [AVCaptureStillImageOutput new];
NSDictionary *imageOutputSettings = [[NSDictionary alloc]initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
imageOutput.outputSettings = imageOutputSettings;
//Video Output
movieOutput = [AVCaptureMovieFileOutput new];
[session addOutput:movieOutput];
[session addOutput:imageOutput];
[session startRunning];
}
- (void)testDevices {
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices) {
NSLog(#"Device name: %#", [device localizedName]);
if ([device hasMediaType:AVMediaTypeVideo]) {
if ([device position] == AVCaptureDevicePositionBack) {
NSLog(#"Device position : back");
}
else {
NSLog(#"Device position : front");
}
}
}
}
#pragma mark - Image capture
- (void)captureImage {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in imageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
NSLog(#"Requesting capture from: %#", imageOutput);
[imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
self.previewView.image = image;
self.previewView.hidden = NO;
}
}];
[self saveButtonFlyIn:self.saveButton];
}
#pragma mark - Video capture
- (void)captureVideo {
NSLog(#"%#", movieOutput.connections);
[[NSFileManager defaultManager] removeItemAtURL:[self outputURL] error:nil];
videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:movieOutput.connections];
[movieOutput startRecordingToOutputFileURL:[self outputURL] recordingDelegate:self];
}
- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections {
for (AVCaptureConnection *connection in connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:mediaType]) {
return connection;
}
}
}
return nil;
}
#pragma mark - Show Last Recording
- (void)presentRecording {
NSLog(#"unplaying");
NSLog(#"%#",[self outputURL]);
}
- (IBAction)loadAssetFromFile {
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[self outputURL] options:nil];
NSString *tracksKey = #"tracks";
[asset loadValuesAsynchronouslyForKeys:#[tracksKey] completionHandler:^{
dispatch_async(dispatch_get_main_queue(),^{
NSError *error;
AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey
error:&error];
if (status == AVKeyValueStatusLoaded) {
playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:#"status"
options:NSKeyValueObservingOptionInitial
context:&ItemStatusContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:playerItem];
player = [AVPlayer playerWithPlayerItem:playerItem];
[playerView setPlayer:player];
}
else {
NSLog(#"The asset's tracks were not loaded:\n%#", [error localizedDescription]);
}
});
}];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == &ItemStatusContext) {
dispatch_async(dispatch_get_main_queue(),^{
[self syncUI];
});
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
[player seekToTime:kCMTimeZero];
}
- (void)syncUI {
if ((player.currentItem != nil) &&
([player.currentItem status] == AVPlayerItemStatusReadyToPlay)) {
self.button.enabled = YES;
}
else {
self.button.enabled = NO;
}
}
#pragma mark - AVCaptureFileOutputRecordingDelegate
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
if (!error) {
NSLog(#"Success!!!!");
} else {
NSLog(#"Error: %#", [error localizedDescription]);
}
}
#pragma mark - Recoding Destination URL
- (NSURL *)outputURL {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:VIDEO_FILE];
return [NSURL fileURLWithPath:filePath];
}
#pragma mark - Buttons
- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
NSLog(#"Press");
self.button.backgroundColor = [UIColor greenColor];
[self captureVideo];
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"Unpress");
self.button.backgroundColor = [UIColor redColor];
[movieOutput stopRecording];
[self performSelector:#selector(loadAssetFromFile)];
[player play];
}
}
- (UIButton *)createButtonWithTitle:(NSString *)title chooseColor:(UIColor *)color {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(self.view.center.x, self.view.frame.size.height - 100, 85, 85)];
button.layer.cornerRadius = button.bounds.size.width / 2;
button.backgroundColor = color;
button.tintColor = [UIColor whiteColor];
[self.view addSubview:button];
return button;
}
- (UIButton *)createSaveButton {
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width, self.view.frame.size.height - 100, 85, 85)];
button.layer.cornerRadius = button.bounds.size.width / 2;
button.backgroundColor = [UIColor greenColor];
button.tintColor = [UIColor whiteColor];
button.userInteractionEnabled = YES;
[button setTitle:#"save" forState:UIControlStateNormal];
[self.view addSubview:button];
return button;
}
- (void)saveButtonFlyIn:(UIButton *)button {
CGRect movement = button.frame;
movement.origin.x = self.view.frame.size.width - 100;
[UIView animateWithDuration:0.2 animations:^{
button.frame = movement;
}];
}
- (void)saveButtonFlyOut:(UIButton *)button {
CGRect movement = button.frame;
movement.origin.x = self.view.frame.size.width;
[UIView animateWithDuration:0.2 animations:^{
button.frame = movement;
}];
}
#pragma mark - Save actions
- (void)saveActions {
[self saveButtonFlyOut:self.saveButton];
self.previewView.image = nil;
self.previewView.hidden = YES;
}
#end
The approach was overly complex. Where you went wrong was 1) not loading the url properly and 2) not adding the 'player layer' sublayer to the main view.
Here is an example of successful playback:
//TestURL
self.videoURL = [NSURL URLWithString:(NSString *)[self.selectedVideo objectForKey:#"source"]];
//Video
self.player = [AVPlayer playerWithPlayerItem:[[AVPlayerItem alloc]initWithAsset:[AVAsset assetWithURL:self.videoURL]]];
//Player layer
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
self.playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 3);
[self.view.layer addSublayer:self.playerLayer];
[self.player play];
All you would need to do is redirect the url to the one you just saved:
self.videoURL = [self outputURL];

CoreData - could not locate an NSManagedObjectModel

I'm getting the error below, I don't know what I'm doing wrong.
I guess there is the managedobject which cannot be located, but... arf !
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Boxes''
here is my .m ( only the two main functions )
- (void)loadCoreData
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Test" object:self];
context = [app managedObjectContext];
NSError *err;
// GET THE JSON
NSString *urlString = [NSString stringWithFormat:#"http://localhost:8888/json.txt"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
NSMutableArray *json = (NSMutableArray* )[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
// FILL THE ENTITY
for (int i = 0; i != 7; i++)
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes" inManagedObjectContext:context];
boxes.name = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"name"] ;
boxes.sexe = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"sexe"] ;
boxes.topic = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"topic"] ;
boxes.number = [NSNumber numberWithInt:[[[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"number"] intValue]];
}
request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Boxes" inManagedObjectContext:context];
[request setEntity:entity];
arrayForPredicate = [context executeFetchRequest:request error:&err];
}
- (void) fillSexArray:(NSString *)sexe
{
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH SEXE EQUAL TO
NSPredicate *sex;
if ([sexe isEqualToString:#"both"])
{
sex = [NSPredicate predicateWithFormat:#"sexe = %# OR sexe = %#", #"female", #"male"];
}
else
{
sex = [NSPredicate predicateWithFormat:#"sexe = %#", sexe];
}
NSArray *BoxWithSex = [arrayForPredicate filteredArrayUsingPredicate:sex];
NSMutableArray *mutableArray = [self createMutableArray:BoxWithSex];
// NSLog(#"%#", [[mutableArray objectAtIndex:1] valueForKey:#"name"]);
// NSUInteger numObjects = [mutableArray count];
}
my .h :
#interface AddViewController : UIViewController
{
IBOutlet UIButton *male;
IBOutlet UIButton *female;
IBOutlet UIButton *couple;
UIButton *maleBtn;
BOOL flag;
NSArray *arrayForPredicate;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *context;
NSFetchRequest *request;
}
#property (nonatomic, retain) WonderAppDelegate *app;
- (void) fillSexArray:(NSString *)sexe;
- (NSMutableArray *)createMutableArray:(NSArray *)array;
- (void)loadCoreData;
- (void)sexeButtonPressed;
- (void)sexeArray;
#end
EDIT creating the managedObject :
+ (id)boxWithDictionary:(NSDictionary *)dict withManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes"
inManagedObjectContext:managedObjectContext];
boxes.name = [dict objectForKey:#"name"];
boxes.sexe = [dict objectForKey:#"sexe"];
boxes.topic = [dict objectForKey:#"topic"];
boxes.number = [dict objectForKey:#"number"];
return boxes;
}
This is my .m and it is working like that but i don't want the code of the function Add there i want it on loadCoreData.
//
// AddViewController.m
// CoreDataTuto
//
// Created by Clement Yerochewski on 30/04/12.
// Copyright (c) 2012 Weblib. All rights reserved.
//
#import "AddViewController.h"
#import "Boxes.h"
#implementation AddViewController
#synthesize app, context;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 768, 44)];
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:#"Add Detail"];
[navBar pushNavigationItem:navItem animated:NO];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancel)];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonItemStyleBordered target:self action:#selector(add)];
navItem.leftBarButtonItem = cancelButton;
navItem.rightBarButtonItem = addButton;
[self.view addSubview:navBar];
app = [[UIApplication sharedApplication] delegate];
}
return self;
}
- (void) add{
[self dismissModalViewControllerAnimated:YES];
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH A LENGTH NAME <= 5
// NSPredicate *length;
// length = [NSPredicate predicateWithFormat:#"name.length <= 5"];
// NSArray *BoxWithCheapPrice = [array filteredArrayUsingPredicate:length];
// NSLog(#"Box %#", BoxWithCheapPrice);
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH PRICE BETWEEN $MIN AND $MAX
// NSNumber *min = [NSNumber numberWithInteger:30];
// NSNumber *max = [NSNumber numberWithInteger:100];
// NSPredicate *between;
// between = [NSPredicate predicateWithFormat:#"number BETWEEN %#", [NSArray arrayWithObjects:min, max, nil]];
// NSArray *BoxWithPriceBetween = [array filteredArrayUsingPredicate:between];
// NSLog(#"Box %#", BoxWithPriceBetween);
// NSLog(#"%#", [BoxWithPriceBetween valueForKey:#"name"]);
}
- (NSMutableArray *)createMutableArray:(NSArray *)array
{
return [NSMutableArray arrayWithArray:array];
}
- (IBAction) sexeChoosen: (id) sender
{
switch ( ((UIButton*)sender).tag ){
case 0:
[self fillSexArray:#"male"];
break;
case 1:
[self fillSexArray:#"female"];
break;
default:
[self fillSexArray:#"both"];
}
[self sexeButtonPressed];
}
- (void)sexeButtonPressed
{
if (flag)
{
UIImage * maleImg2 = [UIImage imageNamed:#"pressed.png"];
[maleBtn setImage:maleImg2 forState:UIControlStateNormal];
flag = NO;
[self sexeArray];
}
else
{
UIImage * maleImg1 = [UIImage imageNamed:#"unpressed.png"];
[maleBtn setImage:maleImg1 forState:UIControlStateNormal];
flag = YES;
[self sexeArray];
}
}
- (void)sexeArray
{
}
- (void)loadCoreData
{
}
- (void) fillSexArray:(NSString *)sexe
{
context = [app managedObjectContext];
// GET THE JSON
NSString *urlString = [NSString stringWithFormat:#"http://localhost:8888/json.txt"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
NSError *err;
NSMutableArray *json = (NSMutableArray* )[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
// FILL THE ENTITY
for (int i = 0; i != 7; i++)
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes" inManagedObjectContext:context];
boxes.name = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"name"] ;
boxes.sexe = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"sexe"] ;
boxes.topic = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"topic"] ;
boxes.number = [NSNumber numberWithInt:[[[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"number"] intValue]];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Boxes" inManagedObjectContext:context];
[request setEntity:entity];
arrayForPredicate = [context executeFetchRequest:request error:&err];
NSPredicate *sex;
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH SEXE EQUAL TO
if ([sexe isEqualToString:#"both"])
{
sex = [NSPredicate predicateWithFormat:#"sexe = %# OR sexe = %#", #"female", #"male"];
}
else
{
sex = [NSPredicate predicateWithFormat:#"sexe = %#", sexe];
}
NSArray *BoxWithSex = [arrayForPredicate filteredArrayUsingPredicate:sex];
NSMutableArray *mutableArray = [self createMutableArray:BoxWithSex];
NSLog(#"SEXE CHOOSEN %#", mutableArray);
// NSLog(#"%#", [[mutableArray objectAtIndex:1] valueForKey:#"name"]);
NSUInteger numObjects = [mutableArray count];
NSLog(#"%d", numObjects);
}
- (void) cancel{
[self dismissModalViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
flag = YES;
maleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
maleBtn.frame = CGRectMake(40, 47, 107, 75);
[maleBtn setTitle:#"male" forState:UIControlStateNormal];
UIImage * maleImg1 = [UIImage imageNamed:#"unpressed.png"];
[maleBtn setImage:maleImg1 forState:UIControlStateNormal];
[maleBtn addTarget:self action:#selector(sexeChoosen:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:maleBtn];
[self loadCoreData];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Have you updated your model after creating the persistent store? Try to delete your app from the simulator (or the database file) and run it again..

Objective C: Adding Images on different pages

I am new to trying to create a book app adapting the page-based application of the new xcode just using the single view app, because it is quite confusing learning the template.
i found this code and i am trying to replace the HTML content of this work to UIImageView but i failed.
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 11; i++)
{
NSString *contentString = [[NSString alloc]
initWithFormat:#"<html><head></head><body><h1>Chapter %d</h1><p>This is the page %d of content displayed using UIPageViewController in iOS 5.</p></body></html>", i, i];
[pageStrings addObject:contentString];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
what i am trying to is to display different images per page.
here is what i did. (i know it is so wrong i just tried it)
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 11; i++)
{
NSArray *photos = [[NSArray arrayWithObjects:
[UIImage imageNamed:#"p1.png"],
[UIImage imageNamed:#"p2.png"],
[UIImage imageNamed:#"p3.png"],
[UIImage imageNamed:#"p4.png"],
nil];
[pageStrings addObject:photos];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
and it has UIWebView in each page. is it possible that if i replace it with UIImageView it will run?
Here's the rest of the code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self createContentPages];
NSDictionary *options =
[NSDictionary dictionaryWithObject:
[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin]
forKey: UIPageViewControllerOptionSpineLocationKey];
self.pageController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options: options];
pageController.dataSource = self;
[[pageController view] setFrame:[[self view] bounds]];
contentViewController *initialViewController =
[self viewControllerAtIndex:0];
NSArray *viewControllers =
[NSArray arrayWithObject:initialViewController];
[pageController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self addChildViewController:pageController];
[[self view] addSubview:[pageController view]];
[pageController didMoveToParentViewController:self];
}
- (contentViewController *)viewControllerAtIndex:(NSUInteger)index
{
// Return the data view controller for the given index.
if (([self.pageContent count] == 0) ||
(index >= [self.pageContent count])) {
return nil;
}
// Create a new view controller and pass suitable data.
contentViewController *dataViewController =
[[contentViewController alloc]
initWithNibName:#"contentViewController"
bundle:nil];
dataViewController.dataObject =
[self.pageContent objectAtIndex:index];
return dataViewController;
}
- (NSUInteger)indexOfViewController:(contentViewController *)viewController
{
return [self.pageContent indexOfObject:viewController.dataObject];
}
- (UIViewController *)pageViewController:
(UIPageViewController *)pageViewController viewControllerBeforeViewController:
(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:
(contentViewController *)viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:
(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:
(contentViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageContent count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
on subclass
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[webView loadHTMLString:dataObject
baseURL:[NSURL URLWithString:#""]];
}
All time you may use the pictures inside HTML page using the HTML tag <IMG>. So, no the reason to use UIImageView.
Use your createContentPages() method with this one small change (UIImage alone don't represent anything you can put on a "view" Instead you need to use a UIImageView which holds UIImages):
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 11; i++)
{
NSArray *photos = [[NSArray arrayWithObjects:
[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"p1.png"] autorelease],
[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"p2.png"] autorelease],
[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"p3.png"] autorelease],
[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"p4.png"] autorelease],
nil];
[pageStrings addObject:photos];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
You can use the code from the main controller (the big block of code that you posted).
The only changes you'll need to make are in what you're calling the "subclass." (really it's the UIPageViewController that handles showing the actual pages).
In that UIPageViewController remove the "webView" (UIWebView). This is probably done in the .xib file (doesn't look like it's added in the code). Then make, viewWillAppear in the UIPageViewController look like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view = dataObject;
}
That should do the trick. Basically, we are no longer using the UIWebView to show HTML data, and instead just adding the dataObject (a UIImageView) as a subview of the UIPageViewController. Hope this helps!

webViewDidFinishLoad not firing when UIWebView opens a PDF

Here is my code:
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
/* Add Content Loading Banner */
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[self.view addSubview:linkLoadView];
linkLoadView.alpha = 1.0;
}
/* Handle PDF Opening */
NSURL *url = [request URL];
NSString *urlString = [url absoluteString];
if([urlString rangeOfString:#".pdf"].location == NSNotFound){
return true;
} else {
NSURL *filePath = [NSURL URLWithString:urlString];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:filePath];
[pdfViewer loadRequest:requestObj];
[self.view addSubview:topView];
[self.view addSubview:linkLoadView];
return false;
}
}
Basically what this does is detect a PDF link from within my UIWebView webView and loads it into an additional UIWebView pdfViewer (found on a View called topView). I then have a function as below:
- (void) webViewDidFinishLoad:(UIWebView *)theWebView{
//for webView
[UIView animateWithDuration:2
animations:^{
loadingView.alpha = 0.0;
linkLoadView.alpha = 0.0;
}
completion:^(BOOL finished){
[loadingView removeFromSuperview];
[linkLoadView removeFromSuperview];
}];
}
The above function doesn't fire at all for the pdfViewer web view, but does for the webView web view. How do I fix this?
Here is my setup settings for both webViews, on the viewDidLoad method.
//Options for
webView.delegate = self;
webView.scalesPageToFit = YES;
for (id subview in webView.subviews)
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
//Options for
pdfViewer.delegate = self;
pdfViewer.scalesPageToFit = YES;
for (id subview in pdfViewer.subviews)
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
Make sure that the pdfViewer delegate is set properly and you will probably need to adjust the loading code.
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
/* Add Content Loading Banner */
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[self.view addSubview:linkLoadView];
linkLoadView.alpha = 1.0;
}
/* Handle PDF Opening */
NSURL *url = [request URL];
NSString *urlString = [url absoluteString];
if(webview != pdfViewer)
{
if([urlString rangeOfString:#".pdf"].location == NSNotFound){
return true;
}
else {
NSURL *filePath = [NSURL URLWithString:urlString];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:filePath];
[pdfViewer loadRequest:requestObj];
[self.view addSubview:topView];
[self.view addSubview:linkLoadView];
return false;
}
}
return true;
}