I have a form on the ipad which has many textfield and a button at the end. There are some fields which come under the keyboard when it is active. In order to pull the hidden texfield behind the keyboard to be visible I am using the following code.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField:textField up:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
_scrollView.frame=CGRectMake(0, 0, 1024, 655);
[self animateTextField:textField up:NO];
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
CGPoint temp = [textField.superview convertPoint:textField.frame.origin toView:nil];
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait)
{
// NSLog(#"portrait");
if(up)
{
int moveUpValue = temp.y+textField.frame.size.height;
animatedDis = 264-(1024-moveUpValue-5);
}
}
else if(orientation == UIInterfaceOrientationPortraitUpsideDown)
{
if(up)
{
int moveUpValue = 1004-temp.y+textField.frame.size.height;
animatedDis = 264-(1004-moveUpValue-5);
}
}
else if(orientation == UIInterfaceOrientationLandscapeLeft)
{
if(up)
{
int moveUpValue = temp.x+textField.frame.size.height;
animatedDis = 352-(768-moveUpValue-5);
}
}
else
{
if(up)
{
int moveUpValue = 768-temp.x+textField.frame.size.height;
animatedDis = 352-(768-moveUpValue-5);
_scrollView.frame = CGRectMake(0, 0, 1024, 655-240);
}
}
if(animatedDis>0)
{
const int movementDistance = animatedDis;
const float movementDuration = 0.3f;
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: nil context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
if (orientation == UIInterfaceOrientationPortrait)
{
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
}
else if(orientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
}
else if(orientation == UIInterfaceOrientationLandscapeLeft)
{
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
}
else
{
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
}
[UIView commitAnimations];
}
}
I am also using the scroll view. My issue is that when the keyboard is active and i press my button it take me to the next screen. Now if i navigate back, the keyboard is active and the prior animations are set. Now if i hide the keyboard, the entire view scrolls down leaving a black portion on top. How to handle this situation?
Okay. After much research I found a simple method. It is the use of notifications.
In my viewDidLoad i added these two keyboard notifications.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
These are the 2 selector methods:
-(void)keyboardWasShown:(NSNotification *)aNotification
{
if (displayKeyboard==YES) {
return;
}
NSDictionary* info = [aNotification userInfo];
NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
NSLog(#"kbw====%fkbh====%f",keyboardSize.width,keyboardSize.height);
offset = _scrollView.contentOffset;
CGRect viewFrame = _scrollView.frame;
NSLog(#"svw====%fsvh===%f",viewFrame.size.width,viewFrame.size.height);
viewFrame.size.height -= keyboardSize.height-49;
NSLog(#"new view hgt =====%f",viewFrame.size.height);
_scrollView.frame = viewFrame;
CGRect textFieldRect = [activeField frame];
textFieldRect.origin.y += 10;
[_scrollView scrollRectToVisible: textFieldRect animated:YES];
displayKeyboard = YES;
}
-(void)keyboardWillBeHidden:(NSNotification *)aNotification
{
if (!displayKeyboard) {
return;
}
_scrollView.frame = CGRectMake(0, 0, 1024, 655);
_scrollView.contentOffset =offset;
displayKeyboard = NO;
}
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField {
activeField = textField;
return YES;
}
displayKeyboard, offset and activeField are declared in .h file.
Also remember to remove the notifications in viewDidDisappear:animated
Although this method is quite different than the previous one stated, this one does not leave a black portion on the top while navigating between classes when the uikeyboard is active.
Also what i noticed was if i used the deprecated UIKeyboardBoundsUserInfoKey i used to get the correct width and height of the keyboard(i am working only in landscape mode). Whereas when i used UIKeyboardFrameBeginUserInfoKey the width and height values were interchanged. I am still trying to figure out this problem.
Also when the keyboard used to appear, a fixed space of 49px was appended to above it. I assumed that that was my tabbar height and therefore subtracted 49.
Related
I should be beyond this, but I can't get to the bottom of this error. I'm trying to write a sketch that records the feed of my Mac camera and stores each recording "session" into a PImage array, then adds that to a list of sessions (a PImage[] ArrayList). I'm using a 'Replay' class to access the images stored in memory to and replay them at a random position. The code below should be ready to be copied straight into the IDE.
Any help would be greatly appreciated. I have no idea why the replay objects are always displaying the live image. Thanks!
import processing.video.*;
Capture cam;
ArrayList<PImage[]> allImages;
ArrayList<PImage> currentImages;
ArrayList<Replay> replays;
boolean recording = false;
boolean finishedSaving = true;
int currentIndex = 0;
void setup() {
size(1056, 704, P2D);
frameRate(30);
allImages = new ArrayList<PImage[]>();
currentImages = new ArrayList<PImage>();
replays = new ArrayList<Replay>();
String[] cams = Capture.list();
if (cams.length == 0) {
println("No cams!");
exit();
} else {
cam = new Capture(this, 1056, 704, cams[0], 30);
cam.start();
}
}
void draw() {
background(0);
if (cam.available() == true) {
cam.read();
}
for (Replay r : replays) {
r.display();
}
if (recording) {
currentImages.add(cam);
noFill();
stroke(255, 0, 0);
strokeWeight(5);
rect(0, 0, cam.width/3, cam.height/3);
} else {
saveToArray();
}
image(cam, 0, 0, cam.width/3, cam.height/3);
}
void saveToArray() {
if (!finishedSaving) {
PImage[] tempImages = currentImages.toArray(new PImage[currentImages.size()]);
allImages.add(tempImages);
currentImages.clear();
println("Finished saving to allImages array");
println("allImages array size now = " + allImages.size());
replays.add(new Replay(currentIndex));
println("Added new Replay (index: " + currentIndex + ")");
currentIndex++;
finishedSaving = true;
println();
}
}
void keyPressed() {
if (key == 'r' || key == 'R') {
recording = !recording;
println("Recording: " + recording);
finishedSaving = false;
}
}
class Replay {
PVector position;
float w, h;
PImage[] images;
int count;
Replay(int allImagesIndex) {
w = cam.width/3;
h = cam.height/3;
position = new PVector(random(width-w), random(height-h));
count = 1;
images = allImages.get(allImagesIndex);
}
void display() {
image(images[count], position.x, position.y, w, h);
count++;
if (count > images.length-1) count = 1;
}
}
Looks like this was due to the camera feed always being assignment to each individual image. To get a "copy" of the "current" video stream frame, I just added .get() to the feed so it fetches the pixels and stores them in a PImage variable.
currentImages.add(cam.get());
I am not able to sort of where is the mistake in my code . When i click the "Submit" button then the keyboard rises again. Here i am using the NSNotificatioCenter which scrolls the view according to keyboard height.
Have a look on code below.
-(void)viewDidLoad
{
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES];
// Register for the events
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
// Setup content size
_scrollView.contentSize = CGSizeMake(SCROLLVIEW_CONTENT_WIDTH,SCROLLVIEW_CONTENT_HEIGHT);
keyboardVisible = NO;
}
-(void) viewWillDisappear:(BOOL)animated
{
NSLog (#"Unregister for keyboard events");
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void) keyboardDidShow: (NSNotification *)notif
{
NSLog(#"Keyboard is visible");
// If keyboard is visible, return
if (keyboardVisible) {
NSLog(#"Keyboard is already visible. Ignore notification.");
return;
}
// Get the size of the keyboard.
NSDictionary* info = [notif userInfo];
NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
// Save the current location so we can restore
// when keyboard is dismissed
offset = _scrollView.contentOffset;
// Resize the scroll view to make room for the keyboard
CGRect viewFrame = _scrollView.frame;
viewFrame.size.height -= keyboardSize.height;
_scrollView.frame = viewFrame;
CGRect textFieldRect = [activeView frame];
textFieldRect.origin.y += 10;
[_scrollView scrollRectToVisible:textFieldRect animated:YES];
NSLog(#"ao fim");
// Keyboard is now visible
keyboardVisible = YES;
}
-(void) keyboardDidHide: (NSNotification *)notif {
// Is the keyboard already shown
if (!keyboardVisible) {
NSLog(#"Keyboard is already hidden. Ignore notification.");
return;
}
// Reset the frame scroll view to its original value
_scrollView.frame = CGRectMake(0, 0, SCROLLVIEW_CONTENT_WIDTH, SCROLLVIEW_CONTENT_HEIGHT);
// Reset the scrollview to previous location
_scrollView.contentOffset = offset;
// Keyboard is no longer visible
keyboardVisible = NO;
}
-(BOOL) textViewShouldBeginEditing:(UITextView*)textView {
activeView = textView;
return YES;
}
-(void)textViewDidEndEditing:(UITextView *)textView{
if(textView == _textViewFeedback)
[_textViewFeedback resignFirstResponder];
else
[_textViewEmail resignFirstResponder];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
{
if([text isEqualToString:#"\n"]){
[textView resignFirstResponder];
}
return YES;
}
- (IBAction)BtnActionSubmitFeedback:(id)sender {
_textViewEmail.text = nil;
_textViewFeedback.text = nil;
NSString *errorMessage = [self validateForm];
if (errorMessage) {
showAlert(#"Warning", errorMessage, nil, nil, #"Dismiss");
return;
}
}
Add a delegate of UITextField
#interface MyViewController : UIViewController <UITextFieldDelegate>
Now set your textField.delegate = self; in viewDidLoad
Add this delegate method to dismiss Keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
OR
You may Put [self.view endEditing:YES]; in your Submit button action to dismiss Keyboard.
I'm trying to make a UITextView that user could input text and emoticons.
And I got a problem with the cursor displaying.
My goal is to make the cursor appears as normal while selecting emoticon(Keyboard is hidden).
I know it could be done because a app called "Kakao Story" have the feature.
Does anybody have a solution about it?? Thanks.
I found a way to make keyboardView hidden to access my purpose.
Here is the code
+ (void)hideKeyboard
{
for (UIWindow *aWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *possibleKeyboard in [aWindow subviews]) {
UIView *keyboardView = [self getPeripheralHostViewFromView:possibleKeyboard];
if (keyboardView) {
[keyboardView setHidden:YES];
}
}
}
}
+ (void)unhideKeyboard
{
for (UIWindow *aWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *possibleKeyboard in [aWindow subviews]) {
UIView *keyboardView = [self getPeripheralHostViewFromView:possibleKeyboard];
if (keyboardView) {
[keyboardView setHidden:NO];
}
}
}
}
+ (UIView *)getPeripheralHostViewFromView:(UIView *)superView
{
if ([superView.description hasPrefix:#"<UIPeripheralHostView"]) {
return superView;
}else if([superView.description hasPrefix:#"<UIKBInputBackdropView"]) {
return superView.superview;
}else {
for (UIView *subView in superView.subviews) {
UIView *keyboardHostView = [self getPeripheralHostViewFromView:subView];
if (keyboardHostView) {
return keyboardHostView;
}
}
}
return nil;
}
I'm having a strange issue with custom UICollectionViewFlowLayout, my cells contain an imageView, I apply a zoom effect to my cells... however I think that I'm doing something wrong with the Zoom Effect, it's strange, because my cells get scaled correctly, the problem is that the imageView for some cells is not.
Here's the relevant code (I think) for this issue, (note that If I remove the method: - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect or the CATransform3DMakeScale, the problem doesn't seem to appear.)
///// UICollectionViewController.m
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
HICollectionViewCell *cell = (HICollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:COLLECTION_VIEW_CELL_ID forIndexPath:indexPath];
[self customizeCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark - CollectionView FlowDelegate
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(200.0f, 200.0f);
}
#pragma mark - "Private" Methods
- (void)customizeCell:(HICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
UIImageView *view = (UIImageView *)[cell.contentView viewWithTag:kCollectionViewCellSubViewTag_imgView];
if (!view.image) {
view.image = [UIImage imageNamed:#"placeholder.png"];
}
}
The Custom Layout Inherits from UICollectionViewFlowLayout
/////// CustomLayout.m
static const CGFloat ACTIVE_DISTANCE = 200.0f;
static const CGFloat ZOOM_FACTOR = 0.3f;
- (id)init
{
if(self = [super init]) {
self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(200.0f, 0.0f, 200.0f, 0.0f);
self.minimumLineSpacing = 50.0f;
}
return self;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes *attribute in attributes) {
if (CGRectIntersectsRect(attribute.frame, rect)) {
CGFloat distance = CGRectGetMidX(visibleRect) - attribute.center.x;
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
// Apply a zoom factor to cells within ACTIVE_DISTANCE
if (ABS(distance) < ACTIVE_DISTANCE) {
CGFloat zoom = 1.0f + ZOOM_FACTOR * (1.0f - ABS(normalizedDistance));
attribute.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attribute.zIndex = round(zoom);
}
}
}
return attributes;
}
As the FlowLayout appears everything looks fine.
Then I start to scroll and I notice that the background layer of the cells to the right starts to show off (backgroundColor is orange)
As you can see, after two cells, the third one ( that starts to appear, looks OK again ).
Maybe it's an issue with the cell queue and dequeue (and the imageView being re-used or something?).
I am working with IOS 6 UITableView and my problem is that whenever i put the table view into edit mode, the edit control that appears next to the table view cell of deletestyle ( UITableViewCellEditingStyleDelete ) overlaps two labels ( xyzname and xyzcollege ).
I did not have this problem in IOS 5 (with same code).
CODE:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle]pathForResource:#"friends"ofType:#"plist"];
NSDictionary *xyz = [[NSDictionary alloc]initWithContentsOfFile:path];
_names = [xyz objectForKey:#"name"];
_colls = [xyz objectForKey:#"college"];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
NSInteger count =_names.count;
if(self.editing)
{
count++;
}
return count;
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
saumyaTableViewCell *cell;
cell = [_saumyaTable dequeueReusableCellWithIdentifier:#"saumyacell"];
if(indexPath.row < _names.count)
{
cell.xyzname.text = [_names objectAtIndex:indexPath.row];
cell.xyzcollege.text = [_colls objectAtIndex:indexPath.row];
}
else
{
cell.xyzname.text = #"Add name.";
cell.xyzcollege.text = #"Add College";
cell.editingAccessoryType =
UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
-(void)setEditing:(BOOL)editing animated:(BOOL) animated
{
if( editing != self.editing )
{
[super setEditing:editing animated:animated];
[_saumyaTable setEditing:editing animated:animated];
NSArray *indexes = [NSArray arrayWithObject:
[NSIndexPath indexPathForRow:_names.count inSection:0]];
if (editing == YES )
{
[_saumyaTable insertRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationLeft];
}
else
{
[_saumyaTable deleteRowsAtIndexPaths:indexes
withRowAnimation:UITableViewRowAnimationLeft];
}
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row < _names.count)
{
return UITableViewCellEditingStyleDelete;
}
else
{
return UITableViewCellEditingStyleInsert;
}
}
IMAGE DESCRIPTION:
1.UITableViewCell has two labels(xyzname and xyzcollege)
2.UITableViewCellEditingStyleDelete overlaps these two labels when cell goes into edit mode
What is to be done if i want those labels to automatically animate on the right side when my view goes into the edit mode and again animate to their original positions after coming out of the edit mode?
THANK YOU