Recreating the iMessage app [duplicate] - objective-c

This question already has answers here:
Programmatically align a toolbar on top of the iPhone keyboard
(7 answers)
Closed 9 years ago.
I am doing a messaging app and I am trying to duplicate the toolbar on top of the key board with the UITextField and two buttons (camera and done). I know how to put a toolbar on top of the keyboard when you click on a UITextField in the view, but my textfield is on my toolbar. When the UITextField on the toolbar is clicked, I want the keyboard to come up under it and kind of push the toolbar up with it. I also need them to go down together as if they are one thing (like it does in the iMessage app). I have looked up many tutorials but cannot seem to find the answer. What code do I need to do this?? Thank you I AM NOT ASKING HOW TO PUT A TOOLBAR ON TOP OF A KEYBOARD, I AM ASKING HOW TO TRIGGER THE KEYBOARD TO COME UP UNDER THE EXISTING TOOLBAR AND BE TRIGGERED BY THE TEXTVIEW INSIDE SAID TOOLBAR

i have written this code duplicate the effect of iMessage, it uses a open source textview HPGrowingTextView
- (void)organizeView {
textView = [[HPGrowingTextView alloc] initWithFrame:CGRectMake(8, 5, 230, 40)];
textView.contentInset = UIEdgeInsetsMake(0, 5, 0, 5);
textView.minNumberOfLines = 1;
textView.maxNumberOfLines = 4;
// you can also set the maximum height in points with maxHeight
// textView.maxHeight = 200.0f;
textView.returnKeyType = UIReturnKeySend; //just as an example
textView.delegate=self;
textView.font = [UIFont systemFontOfSize:15.0f];
textView.delegate = self;
textView.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(5, 0, 5, 0);
textView.backgroundColor = [UIColor whiteColor];
textView.placeholder = #"Type your Comment here..";
[textView becomeFirstResponder];
UIImage *rawEntryBackground = [UIImage imageNamed:#""];
UIImage *entryBackground = [rawEntryBackground stretchableImageWithLeftCapWidth:13 topCapHeight:22];
UIImageView *entryImageView = [[UIImageView alloc] initWithImage:entryBackground];
entryImageView.frame = CGRectMake(5, 0, 248, 40);
entryImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UIImage *rawBackground = [UIImage imageNamed:#"message-strip.png"];
UIImage *background = [rawBackground stretchableImageWithLeftCapWidth:13 topCapHeight:22];
UIImageView *imageView = [[UIImageView alloc] initWithImage:background];
imageView.frame = CGRectMake(0, 0, _containerView.frame.size.width, _containerView.frame.size.height);
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// view hierachy
[_containerView addSubview:imageView];
[_containerView addSubview:textView];
[_containerView addSubview:entryImageView];
UIImage *sendBtnBackground = [[UIImage imageNamed:#"send"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
doneBtn.frame = CGRectMake(_containerView.frame.size.width - 69, 8, 63, 27);
doneBtn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
[doneBtn setImage:sendBtnBackground forState:UIControlStateNormal];
[doneBtn addTarget:self action:#selector(postButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[_containerView addSubview:doneBtn];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
}
-(void)resignTextView
{
[textView resignFirstResponder];
}
//Code from Brett Schumann
-(void) keyboardWillShow:(NSNotification *)note{
// get keyboard size and loctaion
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// Need to translate the bounds to account for rotation.
keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
NSInteger kbSizeH = keyboardBounds.size.height;
// get a rect for the textView frame
CGRect containerFrame = _containerView.frame;
containerFrame.origin.y -= kbSizeH-50;
////reset the table container view height
CGRect tableContainerFrame=_viewTable.frame;
tableContainerFrame.size.height=self.view.frame.size.height-(kbSizeH+containerFrame.size.height );
//containerFrame.origin.y = self.view.bounds.size.height - (keyboardBounds.size.height + containerFrame.size.height);
// animations settings
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
// set views with new info
_containerView.frame = containerFrame;
_viewTable.frame=tableContainerFrame;
// commit animations
[UIView commitAnimations];
}
-(void) keyboardWillHide:(NSNotification *)note{
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// get a rect for the textView frame
CGRect containerFrame = _containerView.frame;
containerFrame.origin.y = self.view.bounds.size.height - containerFrame.size.height;
// animations settings
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
// set views with new info
_containerView.frame = containerFrame;
// commit animations
[UIView commitAnimations];
}
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height
{
float diff = (growingTextView.frame.size.height - height);
CGRect r = _containerView.frame;
r.size.height -= diff;
r.origin.y += diff;
_containerView.frame = r;
}
-(BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)growingTextView{
if (growingTextView == self->textView) {
[self performSelector:#selector(postButtonAction:)];
return NO;
}
else
return YES;
}

Related

Create a temporary HUD popup notification in Cocoa App

Im trying to have a window pop up to notify the user of an action, kind of like how the Flutter app shows a play/pause notification when a gesture is received.
This comes up for about two seconds and vanishes. The app itself is run from the menu bar so this pop up doesn't take control from whatever application is currently in focus but rather just shows on top of it and cannot be interacted with. I basically want to recreate exactly this. Say in the body of
- (void)popup:(id)sender {}
This is essentially very similar to a toast on android.
Edit: I looked closer at the flutter app and all it does is display two images (.png) one for the huge pause and another to indicate what application its in (in this case iTunes). Question now is how do I display an image like this.
You should take a look at this:
https://github.com/Foxnolds/MBProgressHUD-OSX
or Growl:
http://growl.info/documentation/developer/
To replicate this I added a 'HUD Window" from the interface builder which is just an NSPanel. I then added a image view to the panel and set the panel's colour to clear. I was then able to position the panel where I wanted and overlay the appropriate image.
I'm using this code:
static void showHud(NSString* text, int width, int height, CGFloat duration, int fontSize) {
NSWindow* window = [NSWindow new];
[window setFrame:NSMakeRect(0,0,width,height) display:NO];
[window center];
window.titleVisibility = NSWindowTitleHidden;
window.styleMask = NSWindowStyleMaskBorderless;
window.alphaValue = 0.9;
window.movableByWindowBackground = YES;
[window setLevel: NSStatusWindowLevel];
[window setBackgroundColor: [NSColor clearColor]];
[window setOpaque:NO];
//[window setHasShadow:NO];
[window makeKeyAndOrderFront:NSApp];
NSVisualEffectView *view = [[NSVisualEffectView new] initWithFrame:window.contentView.bounds];;
view.translatesAutoresizingMaskIntoConstraints = NO;
[view setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
[view setMaterial:NSVisualEffectMaterialDark];
[view setState:NSVisualEffectStateActive];
//[view setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
//[view setWantsLayer:NO];
[view setWantsLayer:YES];
view.layer.cornerRadius = 16.;
//view.layer.shouldRasterize = YES;
//view.layer.rasterizationScale = 0.45;
view.layer.shadowOpacity = 0.1; //0.01;
view.layer.edgeAntialiasingMask = kCALayerTopEdge | kCALayerBottomEdge | kCALayerRightEdge | kCALayerLeftEdge;
[window.contentView addSubview:view];
//window.contentView = view;
NSTextField *label = [[NSTextField alloc] initWithFrame:view.bounds];
[label setBezeled:NO];
[label setDrawsBackground:NO];
[label setEditable:NO];
[label setSelectable:NO];
label.stringValue = text;
label.alignment = NSTextAlignmentCenter;
label.textColor = [NSColor whiteColor];
label.backgroundColor = [NSColor clearColor];
label.font = [NSFont fontWithName:#"Arial-BoldMT" size:fontSize];
//NSRect titleRect = [label titleRectForBounds:view.bounds];
NSSize cellSize = [label.cell cellSizeForBounds:view.bounds];
NSSize strSize = cellSize; // [label.attributedStringValue size];
NSRect frame = view.frame;
frame.origin.y = frame.size.height / 2 - strSize.height / 2;
frame.size.height = strSize.height;
label.frame = frame;
[view addSubview:label];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = duration;
window.animator.alphaValue = 0.;
} completionHandler:^{
[window close];
}];
}

Recognize a UIButton Tap inside a UIScrollView

I have a UIScrollView into which I add UIImageViews dynamically.
On the storyboard
After running the program
The code for adding an image is on my custom class. The class isn't assigned to any view:
- (id)initWithModel:(UIScrollView *)scroller page:(NSInteger)page image:(UIImage*)image{
self = [super init];
if (self) {
_scrollView = scroller;
_imageScrollIndex = page;
_image = image;
_frame = _scrollView.bounds;
_frame.origin.x = _frame.size.width * _imageScrollIndex;
_frame.origin.y = 0.0f;
_frame = CGRectInset(_frame, 10.0f, 0.0f);
_imageView = [[UIImageView alloc] initWithImage:_image];
_imageView.contentMode = UIViewContentModeScaleAspectFit;
_imageView.frame = _frame;
//adding delete image button
CGRect frame = _imageView.frame;
frame.origin.x = frame.size.width/2;
frame.origin.y = -frame.size.height/2+45;
//_imageView.userInteractionEnabled = YES;
UIButton *deleteImgButton = [[UIButton alloc] initWithFrame:frame];
deleteImgButton.userInteractionEnabled = YES;
[deleteImgButton addTarget:self action:#selector(clickedDeleteButton:)forControlEvents:UIControlEventTouchUpInside];
[deleteImgButton setImage:[UIImage imageNamed:#"close.png"] forState:UIControlStateNormal];
[_imageView addSubview:deleteImgButton];
////
[_scrollView addSubview:_imageView];
}
return self;
}
- (void)clickedDeleteButton:(UIButton*)button
{
printf("hi:\n");
}
I want to be:
Be able to recognize scroll event (Thus I think I need to keep the userinteractionenabled YES for the scrollView
Be able to recognize a tap on the delete button of the image
Any ideas how?
_scrl_ipad.contentSize = CGSizeMake(768,273 * temp);
_scrl_ipad.showsVerticalScrollIndicator=NO;
UIButton *btn_scrl=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_scrl setFrame:CGRectMake(0,0, 328, 243)];
btn_scrl.tag=i-1;
[btn_scrl addTarget:self action:#selector(btn_scrl_tag:) forControlEvents:UIControlEventTouchUpInside];
[_scrl_ipad addSubview:btn_scrl];
-(IBAction)btn_scrl_tag:(id)sender
{
UIButton *btn = (UIButton *)sender;
NSLog(#"%d",btn.tag);
}

I need to popup actionsheet above tabbar in my present viewcontroller, but it should not overlap tabbar(i need to see tabbar clearly)

I need to popup transperant actionsheet above tabbar in my present viewcontroller, but it should not overlap tabbar(i need to see tabbar clearly).
To create a transparant background on a UIActionsheet you have to set the delegate and then you can do:
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
[actionSheet.layer setContents:nil];
}
To create a custom UIView that animates in from the bottom you can do>
bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, 250)];
bottomView.backgroundColor = [UIColor redColor];
bottomView.hidden = YES;
[self.view addSubview:bottomView];
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeCustom];
testButton.frame = CGRectMake(20, 50, 280, 40);
testButton.backgroundColor = [UIColor greenColor];
[bottomView addSubview:testButton];
[self animateBottomViewIn];
And have the following methods:
-(void)animateBottomViewIn
{
bottomView.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
bottomView.frame = CGRectMake(0, self.view.frame.size.height - bottomView.frame.size.height, self.view.frame.size.width, bottomView.frame.size.height);
} completion:^(BOOL finished) { }];
}
-(void)animateBottomViewOut
{
[UIView animateWithDuration:0.3 animations:^{
bottomView.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, bottomView.frame.size.height);
} completion:^(BOOL finished) {
bottomView.hidden = YES;
}];
}

How to animate zooming UIView WITH SUBVIEWS?

This code does the following: It takes a 'snapshot' of a NavigationController meant to disappear. Then the snapshot is added to the view of a container view controller, slides away and reveals the new NavigationController. To create the 'Pop-Out-Effect' the midAnFrame makes the view a bit bigger than the actual view. After that postAnFrame provides the sliding out of the container view's frame. Works great, the only problem is that the subviews of animationContainer don't resize like their superView during the animation.
- (void)bringUpSettingsNavigationController {
CGFloat gradientWidth = 20;
CGFloat frameIncrease = 10;
CGRect preAnFrame = CGRectMake(- gradientWidth, 0, self.view.frame.size.width + gradientWidth, self.view.frame.size.height);
CGRect midAnFrame = CGRectMake(-(frameIncrease + gradientWidth), - frameIncrease, preAnFrame.size.width + (2*frameIncrease), preAnFrame.size.height + (2*frameIncrease));
CGRect postAnFrame = CGRectMake(midAnFrame.size.width, midAnFrame.origin.y, midAnFrame.size.width, midAnFrame.size.height);
UIView *animationContainer = [[UIView alloc]initWithFrame:preAnFrame];
animationContainer.backgroundColor = [UIColor clearColor];
animationContainer.autoresizesSubviews = YES;
self.topImageView = [[UIImageView alloc]initWithImage:[self topImageFromView:self.view]];
self.topImageView.frame = CGRectMake(gradientWidth, 0, preAnFrame.size.width - gradientWidth, preAnFrame.size.height);
[animationContainer addSubview:self.topImageView];
self.topImageView.clipsToBounds = YES;
UIView *gradientView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, gradientWidth, preAnFrame.size.height)];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = gradientView.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor], (id)[[UIColor colorWithWhite:0 alpha:.5] CGColor], nil];
gradientLayer.startPoint = CGPointMake(0, 0.5);
gradientLayer.endPoint = CGPointMake(1.0, 0.5);
[gradientView.layer insertSublayer:gradientLayer atIndex:0];
gradientView.backgroundColor = [UIColor clearColor];
[animationContainer addSubview:gradientView];
gradientView.clipsToBounds = YES;
[self.view addSubview:animationContainer];
BYSettingsNavigationController *settingsNavigationController = [[BYSettingsNavigationController alloc]initWithRootViewController:[[BYSettingsViewController alloc]init]];
[self addChildViewController:settingsNavigationController];
settingsNavigationController.view.frame = self.view.bounds;
[self.view insertSubview:settingsNavigationController.view belowSubview:animationContainer];
[settingsNavigationController didMoveToParentViewController:self];
[UIView animateWithDuration:0.2 animations:^{
animationContainer.frame = midAnFrame;
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 animations:^{
animationContainer.frame = postAnFrame;
} completion:^(BOOL finished) {
[self.topImageView removeFromSuperview];
[gradientView removeFromSuperview];
self.topImageView = nil;
}];
}];
[self.currentNavigationController willMoveToParentViewController:nil];
[self.currentNavigationController.view removeFromSuperview];
[self.currentNavigationController removeFromParentViewController];
}
Thanks in advance for your ideas and have a great 2013!
Dario
What your doing is not zooming in , your just changing the frame size.
To zoom in you need to change the transformation of the view.
What you need to do is something along this line:
view.transform = CGAffineTransformMakeScale (2.0 , 2.0);
for example to zoom X2

Changing value on a label with UISlider control in WePopoverControler

I am in a process of implementing WePopovercontroller in my app and I have a question on how to implement uislider on it. I am able to show the slider in the UIView and get the action when slider moved but not sure how to set the value of the label in that view. Here is the part of the code
-(void)popoverSliderMoved:(UISlider *) sender{
NSLog(#"slider %f",sender.value);
}
-(IBAction)showSettingsMenu:(UIButton *)sender{
if(!self.popoverSettingsController) {
// Create a label and button for the popover
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
[label setText:#"Bookmark it!"];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor whiteColor]];
[label setTextAlignment:UITextAlignmentCenter];
UISlider *slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 45, 100, 40)];
[slider addTarget:self action:#selector(popoverSliderMoved:) forControlEvents:UIControlEventValueChanged];
UIFont *font = [UIFont boldSystemFontOfSize:20];
[label setFont:font];
CGSize size = [label.text sizeWithFont:font];
CGRect frame = CGRectMake(0, 0, size.width + 10, size.height + 10); // add a bit of a border around the text
label.frame = frame;
UIButton *button = [[UIButton alloc] initWithFrame:label.frame];
[button addSubview:label];
[button addTarget:self action:#selector(popoverButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UIViewController *viewCon = [[UIViewController alloc] init];
[viewCon.view addSubview:slider];
[viewCon.view addSubview:button];
CGRect popOverFrm = CGRectMake(0, 0, frame.size.width + slider.frame.size.width, frame.size.height + slider.frame.size.height);
viewCon.contentSizeForViewInPopover = popOverFrm.size;//CGSizeMake(100, 36);
NSLog(#"Label Frame: %#", NSStringFromCGRect(label.frame));
NSLog(#"Popover size: %#", NSStringFromCGSize(viewCon.contentSizeForViewInPopover));
NSLog(#"ViewCon: %#", NSStringFromCGRect(viewCon.view.frame));
self.popoverSettingsController = [[WEPopoverController alloc] initWithContentViewController:viewCon];
//[self.popoverSettingsController setDelegate:self];
}
if([self.popoverSettingsController isPopoverVisible]) {
[self.popoverSettingsController dismissPopoverAnimated:YES];
// [navPopover setDelegate:nil];
self.popoverSettingsController = nil;
} else {
[self.popoverSettingsController presentPopoverFromRect:CGRectMake(sender.frame.size.width, 0, 200, 57)
inView:self.navigationController.view
permittedArrowDirections:UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown
animated:YES];
}
}
Would i need to use a delegate in this case or a property for this viewcontroller to set the label.
Thanks!!!
Yes using a property would be what I would do.