Dialog like Xcode in OS X - macos

I want to show the dialog with text input as sheet below.
I try with NSAlert but i don't want to show app icon in dialog.
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:kAppTitle];
[alert setInformativeText:kMsgSetDeviceName];
[alert addButtonWithTitle:kButtonOK];
[alert addButtonWithTitle:kButtonCancel];
NSString *deviceName = #"";
NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 24)];
[input setStringValue:deviceName];
[alert setAccessoryView:input];
[alert beginSheetModalForWindow:self.view.window completionHandler:^(NSInteger button) {
}];

You can use http://www.knowstack.com/nsalert-cocoa-objective-c/ link to create custom alert sheet in OSX.
-(void)showCustomSheet
{
{
if (!_customSheet)
//Check the myCustomSheet instance variable to make sure the custom sheet does not already exist.
[NSBundle loadNibNamed: #"CustomSheet" owner: self];
[NSApp beginSheet: self.customSheet
modalForWindow: self.window
modalDelegate: self
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
// Sheet is up here.
}
}
- (IBAction)closeMyCustomSheet: (id)sender
{
[NSApp endSheet:_customSheet];
}
- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
NSLog(#"%s",__func__);
NSLog(#"return Code %d",returnCode);
[sheet orderOut:self];
}
The below method is required to have a different point to show the alert from
- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet
usingRect:(NSRect)rect
{
NSLog(#"%s",__func__);
if (sheet == self.customSheet)
{
NSLog(#"if block");
NSRect fieldRect = [self.showAlertButton frame];
fieldRect.size.height = 0;
return fieldRect;
}
else
{
NSLog(#"else block");
return rect;
}
}

Related

How to close an alert after some time and repeat it every 10 min

In my MAC OSX application. I am throwing a an alert pop up asking user to select yes or no. if user doesnt click any of the choices and may drag it to some corner. So i wanted to autoclose it after some time and again show the same alert. so i can ensure him to take same action.
Alert code i am using is
-(bool)VpnStatusUnableToConnect:(NSString *)alertMessage
{
if (nil != alertMessage) {
NSImage *alertIcon = [NSImage imageNamed:#"dock-alert"]; //my custom image placed in support files
NSAlert *alert = [[NSAlert alloc]init];
[alert addButtonWithTitle:#"Try Again"];
[alert addButtonWithTitle:#"Cancel"];
[alert setMessageText:alertMessage];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setIcon:alertIcon];
[[alert window] setTitle:#"VPN Connection Status"];
[[alert window] setBackgroundColor: NSColor.whiteColor];
if ( [alert runModal] == NSAlertFirstButtonReturn)
{
return 1;
}
else
return 0;
}
return 0;
}
Modify your code as below and give a try
-(void)yourAlert{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle: #"OK"];
[alert setMessageText: #"Attention!!! This a critical Alert."];
[alert setAlertStyle: NSInformationalAlertStyle];
NSTimer *myTimer = [NSTimer timerWithTimeInterval:3
target:self
selector: #selector(killWindow:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSModalPanelRunLoopMode];
int choice = 0;
choice = [alert runModal];
if(choice != 0)
[myTimer invalidate];
}
-(void) killWindow:(NSAlert *)alert with:(NSTimer *) theTimer;
{
NSLog(#"killWindow");
[[alert window] abortModal];
}

UIAlertController Warning Message

I am using the below code for UIAlertController in my project.
if([[[UIDevice currentDevice] systemVersion]floatValue] >= 8.0){
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Input Error"
message:#"Please enter a valid email."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Input Error"
message:#"Please enter a valid email"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
}
I am getting the below waring message:
Warning: Attempt to present <UIAlertController: 0x7f8da58df1f0> on <MBComplaintsViewController: 0x7f8da36454d0> which is already presenting (null)
Kindly guide me how to properly use UIAlertController using Objective C.
Thanks,
Abin Koshy Cheriyan
Yes as per #Alexander you should not be dismissing the alert controller like this explicitly.
As per an apple engineer a new window gets added each time an UIAlertController is displayed so when we go for dismissing it the window is still there though the alert controller disappears.
So there are two ways to handle this -
Way 1 - No explicit dismiss
Do not explicitly dismiss the UIAlertController, let it be done by the user
Way 2 - Use your own window
Simply create a category on UIAertController
Here is the sample code -
.h
#import <UIKit/UIKit.h>
#interface UIAlertController (MyAdditions)
#property(nonatomic,strong) UIWindow *alertWindow;
-(void)show;
#end
In .m
#import "UIAlertController+MyAdditions.h"
#import <objc/runtime.h>
#implementation UIAlertController (MyAdditions)
#dynamic alertWindow;
- (void)setAlertWindow:(UIWindow *)alertWindow {
objc_setAssociatedObject(self, #selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIWindow *)alertWindow {
return objc_getAssociatedObject(self, #selector(alertWindow));
}
- (void)show {
self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
// window level = topmost + 1
UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
self.alertWindow.windowLevel = topWindow.windowLevel + 1;
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:self animated:YES completion:nil];
}
-(void)hide {
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// just to ensure the window gets desroyed
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
To show the alert controller
UIAlertCntroller *alert = ## initialisation##;
// will show the alert
[alert show];
//to dismiss
[alert hide];
[alert dismissViewControllerAnimated:YES completion:nil];
Even you can checkout one of my sample implementation here
I don't know about your problem, but you shouldn't do that
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
It will be anyway dismissed on any of your actions.

UIImagePickerController crashes on launch

I present a viewcontroller to the user with a view that shows a UIButton to record a video. When the user presses the button, my app crashes with the following error:
Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation must return a supported interface orientation!'
My app only supports portrait orientation and the info.plist file reflects properly. I use the same code in another app, found on Ray Wenderlich's site, and it works great. The code for the .h and .m files is below. Any help would be appreciated.
.h
#import <MediaPlayer/MediaPlayer.h>
#import <MobileCoreServices/UTCoreTypes.h>
#import <AssetsLibrary/AssetsLibrary.h>
#interface RecordSwingViewController: UIViewController
-(BOOL)startCameraControllerFromViewController:(UIViewController*)controller
usingDelegate:(id )delegate;
-(void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo;
#property (weak, nonatomic) IBOutlet UIButton *record;
- (IBAction)recordSwing:(id)sender;
#end
.m
#import "RecordSwingViewController.h"
#interface RecordSwingViewController ()
#end
#implementation RecordSwingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)recordSwing:(id)sender {
[self startCameraControllerFromViewController:self usingDelegate:self];
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(BOOL)startCameraControllerFromViewController:(UIViewController*)controller
usingDelegate:(id )delegate {
// 1 - Validattions
if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil)) {
return NO;
}
// 2 - Get image picker
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose movie capture
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
// 3 - Display image picker
[controller presentViewController: cameraUI animated: YES completion:nil];
return YES;
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:NO completion:nil];
// Handle a movie capture
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self,
#selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}
}
-(void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Video Saving Failed"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Video Saved" message:#"Saved To Photo Album"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
#end
Ok, here is the answer, finally.
https://stackoverflow.com/a/12570501/2133494
Basically I needed to add a category to my UIImagePickerController. I tried a lot of other fixes but this worked.
You have implemented the bool for autorotation, but did not specify if it does not auto rotate what else it should do. Try the following after autorotate method.
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
Please remove any of the masks you don't need from the method above and see if this works for you.

FBFriendPickerViewController is loading a empty tableview intermittently

I am using FBFriendPickerViewController to load friends after user signs in. However, an empty table view is being loaded. The friends of the user from fb are not showing up.
Heres the code.
- (IBAction)inviteButtonTouchHandler:(id)sender {
if (!_friendPickerController) {
_friendPickerController = [[FBFriendPickerViewController alloc] initWithNibName:nil bundle:nil];
_friendPickerController.delegate = self;
_friendPickerController.title = #"Select friends";
_friendPickerController.allowsMultipleSelection = NO;
}
[_friendPickerController clearSelection];
[_friendPickerController loadData];
[self presentViewController:_friendPickerController animated:YES completion:nil];
}
This code is called after login which is done like this in appDelegate following the Facebook Tutorial -
- (void)openSession
{
NSArray *permissions = #[#"friends_about_me"];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
You need to add the following code in viewDidLoad method of your viewController.
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession.activeSession openWithCompletionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
switch (state) {
case FBSessionStateClosedLoginFailed:
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
break;
default:
break;
}
}];
}

Game Center? Xcode

I have been working ver hard on Game center. I have tested so many codes I've lost count.
I would love to know how to automatically submit score as well
here are some codes i have used but i am not sure if this will help
-(IBAction)showleaderboard:(id)sender{
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc]init];
if (leaderboardController !=NULL) {
leaderboardController.category = self.currentLeaderboard;
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController:leaderboardController animated:YES];
}
}
-(void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{
[self dismissModalViewControllerAnimated:YES];
[viewController release];
}
-(IBAction)showAchivementLeaderboard:(id)sender{
GKAchievementViewController *achivements = [[GKAchievementViewController alloc]init];
if (achivements !=NULL) {
achivements.achievementDelegate = self;
[self presentModalViewController:achivements animated:YES];
}
}
-(void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController{
[self dismissModalViewControllerAnimated:YES];
[viewController release];
}
self.currentLeaderboard= kEasyLeaderboardID;
if ([gameCenterManager isGameCenterAvailible]) {
self.gameCenterManager= [[[GameCenterManager alloc] init] autorelease];
[self.gameCenterManager setDelegate:self];
[self.gameCenterManager authenticateLocalUser];
}else{
UIAlertView *openURLAlert = [[ UIAlertView alloc] initWithTitle:#"Game Center turned off" message:#"You are not connected to game center." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[openURLAlert show];
[openURLAlert release];
}
To report a score you need to use GKScore as follows;
GKScore *scoreReporter = [[GKScore alloc] initWithCategory:self.gameCategory.leaderboardString];
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil) {
[[KYTGlobals instance] storeScore:score forCategory:self.gameCategory.leaderboardString];
}
}];
The above code allocates and inits a GKScore object using the identifier that you have already set up on game center for the category that you want to report a score for. You update the value for the score and then use reportScoreWithCompletionHandler making sure to test for error so that you can archive the score and report it later.

Resources