Custom AlertView With Background - objective-c

Everybody, I need to set one image on UIAlertView..
I have attached my UIAlertview with image prob..
i have used this code lines..
UIAlertView *theAlert = [[[UIAlertView alloc] initWithTitle:#"Atention"
message: #"YOUR MESSAGE HERE", nil)
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] autorelease];
[theAlert show];
UILabel *theTitle = [theAlert valueForKey:#"_titleLabel"];
[theTitle setTextColor:[UIColor redColor]];
UILabel *theBody = [theAlert valueForKey:#"_bodyTextLabel"];
[theBody setTextColor:[UIColor blueColor]];
UIImage *theImage = [UIImage imageNamed:#"Background.png"];
theImage = [theImage stretchableImageWithLeftCapWidth:16 topCapHeight:16];
CGSize theSize = [theAlert frame].size;
UIGraphicsBeginImageContext(theSize);
[theImage drawInRect:CGRectMake(0, 0, theSize.width, theSize.height)];
theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[theAlert layer] setContents:[theImage CGImage]];
please solve this issue..
i need only image with alert..

Try this...
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"UIAlert View" message:#"hello" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"Close",nil];
UIImage *alertImage = [UIImage imageNamed:#"plus.png"];
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:alertImage];
backgroundImageView.frame = CGRectMake(0, 0, 282, 130);
backgroundImageView.contentMode = UIViewContentModeScaleToFill;
[alert addSubview:backgroundImageView];
[alert sendSubviewToBack:backgroundImageView];
[alert show];
[alert release];

You should consider to not use UIAlertView, but have your own AlertView see TSAlertView for an alternative implementation, that is not derived from UIAlertView.
TSAlertView is allowing you to set your own background image.
Another solution that I am not recommending could be:
You can use introspection: Loop over the UIAlertViews subviews, identify the one that holds the background image set it hidden and place your own backroundimage at an index below/over the original image view.
I found this project: Subclass UIAlertView to customize the look of an alert. It is not working for iOS 4.2+, but with my introspection idea you can make it work again:
change the -layoutSubviews of JKCustomAlert to:
- (void) layoutSubviews {
for (UIView *v in [self subviews]) {
if ([v class] == [UIImageView class]) {
[v setHidden:YES];
}
}
alertTextLabel.transform = CGAffineTransformIdentity;
[alertTextLabel sizeToFit];
CGRect textRect = alertTextLabel.frame;
textRect.origin.x = (CGRectGetWidth(self.bounds) - CGRectGetWidth(textRect)) / 2;
textRect.origin.y = (CGRectGetHeight(self.bounds) - CGRectGetHeight(textRect)) / 2;
textRect.origin.y -= 30.0;
alertTextLabel.frame = textRect;
alertTextLabel.transform = CGAffineTransformMakeRotation(- M_PI * .08);
}
I am NOT promising, that this trick will work in future versions of iOS

A solution I like to use for this is to add a UIView to the ViewController, which mimics the appearance of an alert.
The other property of a UIAlertView is that no other part of the app can be used until the alert is dismissed. This can easily be mimicked by making your UIView a subview of another UIView (with a clear background), which takes up the entire screen.
If you don't want to implement that yourself, here's a Custom Alert View class you could use: https://github.com/shivsak/CustomAlertView

Related

UITextField inside ios7 dont work anymore, older ios work fine

I have a problem with my game, wich was developed in Xcode. When iOS 7 was released, I don't see the textbox for input, but everything else is working. And I don't know how to fix it :(.
http://i.stack.imgur.com/je6Kw.png
http://i.stack.imgur.com/JIvLR.png
Problem look somethink similar :).
Here is my code, button OK don't work too.
-(void)showRegisterAlert:(PlayerInfo*) play
{
NSString * pMessage = [NSString stringWithFormat:#"%#%d%#", #" Your Score is ", play->nScore, #"\n Enter Your Name\n\n"];
CGRect rect = CGRectMake(50, 75, 180, 20);
// CGRect rect = CGRectMake(50, 50, 180, 43);
m_pNameText = [[UITextField alloc] initWithFrame:rect];
m_pNewScoreAlert = [[UIAlertView alloc]initWithTitle:#"NEW HIGHSCORE" message:pMessage delegate:self
cancelButtonTitle:#"OK" otherButtonTitles:nil];
UIColor * color = [[UIColor alloc] initWithWhite:256.0f alpha:100.0f];
[m_pNameText setBackgroundColor: color];
[m_pNameText becomeFirstResponder];
[m_pNewScoreAlert addSubview:m_pNameText];
m_newPlay.nScore = play->nScore;
[m_pNewScoreAlert show];
[color release];
[m_pNewScoreAlert release];
SavePlayInfo();
}
Just take your UIAlertView and set the style type to it.
m_pNewScoreAlert.alertViewStyle = UIAlertViewStylePlainTextInput;

UIActionSheet without background tinting

So I've read this post
But it doesn't seem to deal with the issue of making the background NOT tint to a semi-transparent. I want the content behind the menu with buttons to be clearly visible. Is this even possible?
This is what I have currently
WPSActionSheet *actionSheet = [[WPSActionSheet alloc] initWithCompletion:completion];
[actionSheet setTitle:#""];
[actionSheet addButtonWithTitle:#"Take Photo"];
[actionSheet addButtonWithTitle:#"Choose from Library"];
[actionSheet addButtonWithTitle:#"Skip This Step"];
[actionSheet setCancelButtonIndex:2];
[actionSheet showInView:[self view]];
which shows this
UIActionSheet will always show the "tinted background". There is no way around this. You can however create your own version of the UIActionSheet using a UIView.
Just set the alpha and opaque property of UIActionSheet with delegate method -
(void)willPresentActionSheet:(UIActionSheet *)actionSheet
and it will be visible as you want.
If you want to make background of UIActionSheet transparent you can subclass it and change layoutSubviews
- (void)layoutSubviews
{
[super layoutSubviews];
UIImage* image;
CGSize size = self.frame.size;
UIGraphicsBeginImageContext(size);
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[self layer] setContents:(id)image.CGImage];
}
To add some custom background just add following code to layoutSubviews:
CGRect frame = self.frame;
frame.origin = CGPointZero;
UIImageView* bg = [[UIImageView alloc] initWithFrame:frame];
bg.image = [UIImage imageNamed#"YOUR/IMAGE/NAME"];
[self addSubview:bg];
[self sendSubviewToBack:bg];
Also you can do all those actions in delegate method
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
simply replacing self to actionSheet.
I had the same problem and found a workaround. The UIActionSheet's superview contains a UIView that is used for the tinting. So you can remove the tinting by setting the opacity of this view's layer to 0.
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
NSArray *subviews = actionSheet.superview.subviews;
UIView *tintView = [subviews objectAtIndex:0];
[tintView.layer setOpacity:0.0];
}

Losing Gesture Recognizers in UIPopoverController

I have a class called PhotoBoothController that I use to manipulate an image using gestures. It works fine when I run it on iPhone. However when I run it on iPad, I display the PhotoBoothController inside a UIPopoverController. The image appears fine, however I can't manipulate it as my gestures don't appear to be recognized. I'm not sure how to make the UIPopoverController take control of the gestures.
I present the popovercontroller and configure the view thus:
- (void)presentPhotoBoothForPhoto:(UIImage *)photo button:(UIButton *)button {
//Create a photoBooth and set its contents
PhotoBoothController *photoBoothController = [[PhotoBoothController alloc] init];
photoBoothController.photoImage.image = [button backgroundImageForState:UIControlStateNormal];
//set up all the elements programmatically.
photoBoothController.view.backgroundColor = [UIColor whiteColor];
//Add frame (static)
UIImage *frame = [[UIImage imageNamed:#"HumptyLine1Frame.png"] adjustForResolution];
UIImageView *frameView = [[UIImageView alloc] initWithImage:frame];
frameView.frame = CGRectMake(50, 50, frame.size.width, frame.size.height);
[photoBoothController.view addSubview:frameView];
//Configure image
UIImageView *photoView = [[UIImageView alloc] initWithImage:photo];
photoView.frame = CGRectMake(50, 50, photo.size.width, photo.size.height);
photoBoothController.photoImage = photoView;
//Add canvas
UIView *canvas = [[UIView alloc] initWithFrame:frameView.frame];
photoBoothController.canvas = canvas;
[canvas addSubview:photoView];
[canvas becomeFirstResponder];
[photoBoothController.view addSubview:canvas];
[photoBoothController.view bringSubviewToFront:frameView];
//resize the popover view shown in the current view to the view's size
photoBoothController.contentSizeForViewInPopover = CGSizeMake(frameView.frame.size.width+100, frameView.frame.size.height+400);
self.photoBooth = [[UIPopoverController alloc] initWithContentViewController:photoBoothController];
[self.photoBooth presentPopoverFromRect:button.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
I thought [canvas becomeFirstResponder] might do it but it doesn't appear to make a difference.
Any advice much appreciate, thank you.
UPDATE: adding code as per comment
- (void)viewDidLoad {
[super viewDidLoad];
if (!_marque) {
_marque = [CAShapeLayer layer];
_marque.fillColor = [[UIColor clearColor] CGColor];
_marque.strokeColor = [[UIColor grayColor] CGColor];
_marque.lineWidth = 1.0f;
_marque.lineJoin = kCALineJoinRound;
_marque.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:5], nil];
_marque.bounds = CGRectMake(photoImage.frame.origin.x, photoImage.frame.origin.y, 0, 0);
_marque.position = CGPointMake(photoImage.frame.origin.x + canvas.frame.origin.x, photoImage.frame.origin.y + canvas.frame.origin.y);
}
[[self.view layer] addSublayer:_marque];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[canvas addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapProfileImageRecognizer setNumberOfTapsRequired:1];
[tapProfileImageRecognizer setDelegate:self];
[canvas addGestureRecognizer:tapProfileImageRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return ![gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]];
}
I am working on a similar application, and i can easily manipulate images on the canvas.
1) Check if the userInteractionEnabled property of the canvas is set to YES.
2) You can try adding the gestures to the ImageView's rather than the canvas. (I am guessing u want to zoom , rotate n swipe the images).
some guesses:
is this because viewDidLoad method have been called before cavas property been set? In this case, you could try to add recognizers after present popover in another method such as viewDidAppear.
I also agree that the key may be that UIPopoverController allows interaction to other views outside of the popover. So i suggest to move [canvas becomeFirstResponder]; to the end of the viewDidLoad method in PhotoBoothController and try self.view becomeFirstResponder here because you actually add recognizers to self.view.

Updating UIAlertView Message dynamically and newline character issue

I need to display multiple lines of text in the message of my UIAlertView. I have tried adding a '\n', but it has no effect. It still displays: "This is an examp....".
HOWEVER, if I turn my iPhone to landscape mode it displays the message as I intend it to. And then if I switch BACK to portrait mode it displays correctly there as well.
Update: After further consideration, I suspect it has something to do with the fact that I am updating the current message with a new (and much longer) string. I have already called "show" on the alert view, and am trying to update the message. Perhaps something needs to be redrawn? Like i said before, it displays correctly if I change orientations (doesn't matter which orientation I start in, i still have the same problem). i have already tried "setNeedsDisplay" and "setNeedsLayout".
Although I believe updating the alert view's text while it's being displayed is wrong, the only way I see to change it is this way
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"test" message:#"this is a message\nthis is a new line text" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:#"test button",nil];
[alert show];
//set the new message
NSString *newMessage = [NSString stringWithString:#"Test\nWith a new message with\ncustom new line string\n and a lot\n of new lines\n Yep"];
[alert setMessage:newMessage];
//get the original alert Frame
CGRect alertFrame = alert.frame;
//get the alert view Label
UILabel *alertLabel = [alert.subviews objectAtIndex:2];
//and get the original frame position
CGRect alertLabelFrame = alertLabel.frame;
//see how much space we are needing for the new message and adjust
int heightChange = [newMessage sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(alertLabelFrame.size.width, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap].height - alertLabelFrame.size.height;
alertFrame.size.height += heightChange;
//adjust the Label height to the new height
alertLabelFrame.size.height += heightChange;
//adjust the frame and elements with an animation for smoothness
[UIView animateWithDuration:0.15 delay:0.4 options:(UIViewAnimationCurveEaseIn) animations:^{
[alert setFrame:alertFrame];
alertLabel.frame = alertLabelFrame;
//move any buttons
for (UIView *subView in alert.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
//this is a button move it
UIButton *button = (UIButton*)subView;
CGRect alertButtonFrame = button.frame;
//adjust button Y position to the new height
alertButtonFrame.origin.y += heightChange-5;
button.frame = alertButtonFrame;
}
}
} completion:nil];
For newline use the \n newline character in your text like this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"test" message:#"this is a message\nthis is a new line text" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
Even with setMessage this works:
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setMessage:#"this is\na test"];
[alert show];
[alert release];
Use '\r' symbol. It should break line properly.
Here is some simple code to resize the messages in an alert. Note that the alert's frame needs to be large enough. You can pad the initial alert with a few newlines.
for (UILabel *l in alertView.subviews){
if ([l isKindOfClass:[UILabel class]]){
float w = l.frame.size.width;
[l setNumberOfLines:0];
[l sizeToFit];
CGRect r = l.frame;
r.size.width = w;
l.frame = r;
}
}
Create your own AlertView Category.
AlertWithBlock.h file
#import <UIKit/UIKit.h>
#interface UIAlertView (AlertWithBlock)
- (void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock;
- (void)setDelegateBlock:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock;
+ (void)alertViewWithTitle:(NSString *)title buttonTitle:(NSString *)buttonTitle message:(NSString *)message;
+ (UIAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles delegate:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegate;
#end

how can an UIAlertView button calls another function?

-(void)buPressed{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Game Over"
message:#"YOU LOST! ALL YOUR BASE ARE BELONG TO US!"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Publish", nil];
[alertView show];
[alertView release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex==0){
NSLog(#"%d",buttonIndex);
}
else{
[self bPressed];
}
}
-(void)bPressed{
ModalViewConroller *yeniSayfa=[[ModalViewConroller alloc] init];
yeniSayfa.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:yeniSayfa animated:YES];
[yeniSayfa release];
//Restore to Defaults
[button_1 setSelected:NO];
[button_2 setSelected:NO];
[button_3 setSelected:NO];
[button_4 setSelected:NO];
[button_5 setSelected:NO];
[button_6 setSelected:NO];
slider.value=50.00;
UIImage *image = [UIImage imageNamed:#"Smiley_00025.png"];
imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(81, 43, image.size.width, image.size.height);
[self.view addSubview:imageView];
}
This is my code i want to make the publish button to call bPressed function but it is giving a warning and the program crashes when i touch the publish button i want to open a modalview when i push the publish button can anybody help me?
You need to declare the function in your header file so that other objects (in this case an instance of UIAlertView, since its delegate is set to your class) know that this method exists.
So, in your whatever_class.h file, add the following line below the #interface{ }:
-(void)bPressed;