I have a iPad app, created in XCode 4.6.3, iOS 6.2, ARC and Storyboards.
I create a UIPopover programmatically in SubViewData.m.
#property (strong, nonatomic) UIPopoverController *popover;
// make rectangle to attach popover
CGRect rectangle = CGRectMake( touchPoint.x, touchPoint.y, 110, 1); // 0 height puts arrow on exact touch point
// get addressability to storyboard ViewController
UIViewController *popoverMainView = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"menuView"];
popover = [[UIPopoverController alloc] initWithContentViewController:popoverMainView];
[popover presentPopoverFromRect:rectangle inView:self
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I set notifications in another class (QuickAppointment.m) when a UIButton in the popover has been tapped. I get the notification and issue this code from CalendarViewController.m :
SubViewData *svd = [[SubViewData alloc] init];
[svd.popover dismissPopoverAnimated:YES];
Nothing happens! I don't understand why not... so, what am I doing wrong?
Look at the code you are writing:
SubViewData *svd = [[SubViewData alloc] init];
This creates a completely new and different instance of SubViewData, and not the one that is displaying the popover.
Related
With XCode 4.6 building for iOS 6.1, I'm using a UICollectionView from a storyboard, and I thought that the class implemented scrolling by default. I have made a simple test app with a storyboard that has just a Collection View and one Collection View Cell, and code that implements just collectionView:cellForItemAtIndexPath: and collectionView:numberOfItemsInSection:, calling for enough cells so that scrolling is required to see all the cells.
I thought that with nothing else, I would be able to scroll vertically within the UICollectionView. It shows the visible cells but doesn't scroll. What am I missing here?
Why wouldn't this component allow me to scroll vertically, what am I unable to see?
The implementation code is about as simple as possible:
//
// TestpViewController.h
//
#import <UIKit/UIKit.h>
#interface TestpViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate>
#end
//
// TestpViewController.m
//
#import "TestpViewController.h"
#interface TestpViewController ()
#property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
#end
#implementation TestpViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return 30;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"testCell" forIndexPath:indexPath];
return cell;
}
#end
I just ran into a problem where when I'm adding a new view to my UIViewController there is a small gap on the top. (Appears to be the height of the status bar)
I use pushViewController to show this view, like this:
MapViewController *map = [[[MapViewController alloc] init] autorelease];
[self.navigationController pushViewController:map animated:YES];
In my MapViewController I just create a MKMapView with the same frame as the view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
}
But it turns out to be like this:
I'm not sure if I'm still missing something here ...
Try this instead:
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
The frame of a UIView is in the co-ordinate system of the superview.
The bounds of a UIView, on the other hand, is in the co-ordinate system of the view itself.
In this case, the frame of self.view will be taking into account the status bar (as that's how it sits on the screen) - hence the status bar sized offset at the top.
I am loading a UITableView cell from a nib file in a UITableViewController and the background color that I set in Interface Builder is not being displayed. Why not?
You should use tableView:willDisplayCell:forRowAtIndexPath: to set a background color, as Apple recommends in the Table View Programming Guide for iOS:
A table view sends a tableView:willDisplayCell:forRowAtIndexPath: message to its delegate just before it draws a row. If the delegate chooses to implement this method, it can make last-minute changes to the cell object before it is displayed. With this method, the delegate should change only state-based properties that were set earlier by the table view, such as selection and background color, and not content.
This code does an alternating "zebra stripe" effect:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2 == 0) {
UIColor *altCellColor = [UIColor colorWithWhite:0.7 alpha:0.1];
cell.backgroundColor = altCellColor;
}
}
In my app there are some UICollectionViewCells displaying some info.
When the user taps a button on one of them, I flip the tapped cells with this piece of code:
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:1.0
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^
{
NSLog(#"starting animation");
[UIView transitionFromView:cell.contentView
toView:cell.contentView
duration:.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
completion:^(BOOL finished)
{
NSLog(#"animation end");
}
];
After the cell flips (which is does correctly) the cell is completly white.
Two questions about is:
- why is the cell white after the flip. Shouldn't it display the original info since the fromView is equal to the toView?
- what is the best way to display different content on the back of the cell. I suppose UICollectionViewCell doesn't have something link cell.contentViewBack...
you may have this by now but,
Not sure if this is the 'Best' way to do it, I got this to work by creating a custom UICollectionViewCell, having 2 UIImageViews in the custom cell, and targeting those views in the animation (this only works for you if thats all you want to have in your cells - may help, may not, anywho)
Create new UICollectionViewCell class (mine is called CardCVCell)
In the CardCVCell.h put in you UIImageView outlets
#property (strong, nonatomic) IBOutlet UIImageView *cardImage;
#property (strong, nonatomic) IBOutlet UIImageView *cardBackImage;
I used storyboard - in there I typed in 'CardCVCell' as my custom class on the cell in the Collection View in my scene.
In my View Controller for that scene I have the code you have above, but I use the UIImageViews in the custom cell for the views in the transition (note you have to cast the UICollectionViewCell to your custom class
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// animate the cell user tapped on
CardCVCell *cell = (CardCVCell *)[collectionView cellForItemAtIndexPath:indexPath];
[UIView transitionFromView:cell.cardBackImage
toView:cell.cardImage
duration:.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:^(BOOL finished)
{
if (finished) {
NSLog(#"animation end");
}
}
];
}
I hope this helps someone if not you, if I can help let me know.
cheers
I'm implementing transitions in a WPF application.
First I "save" my 2 FrameworkElement in 2 ImageBrush.
Then I set the Input & Back (Brush) properties of my shader Effect with them.
CustomEffect s = new CustomEffect();
RenderTargetBitmap rtb = new RenderTargetBitmap((int)SourceFrameWorkElement.ActualWidth, (int)SourceFrameWorkElement.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(SourceFrameWorkElement);
ImageBrush ib = new ImageBrush(rtb);
s.Input = ib;
rtb.Render(TargetFrameWorkElement);
ib.ImageSource = rtb;
s.Back = ib;
SourceFrameWorkElement.Effect = s;
Now that all is set up, I want to animate the Time property of my shader, and i've tried this:
DoubleAnimation refDoubleAnimation = new DoubleAnimation(0.0, 1.0, Duration);
Storyboard.SetTarget(refDoubleAnimation, SourceFrameWorkElement);
Storyboard.SetTargetProperty(refDoubleAnimation, new PropertyPath("(Effect).(CustomEffect.Time)");
refStoryboard.Children.Add(refDoubleAnimation);
refStoryboard.Completed += new EventHandler(OnStoryboardCompleted);
refStoryboard.Begin(SourceFrameWorkElement, true);
and i get an InvalidOperationException on the begin method with this message:
"Cannot resolve all property references in the property path '(Effect).(CustomEffect.Time)'.
Verify that applicable objects supports the properties."
But when I use a built in Effect like BlurEffect, it works....
Can someone tell me where i'm wrong ?
Edit:
I've also tried
SourceElement.Effect.BeginAnimation(SlideInEffect.TimeProperty, refDoubleAnimation)
instead of using the storyboard, I don't get an exception but the second image pop instantly and the animation is not playing
The solution was to use BeginAnimation ^^
In fact, I had the second image with opacity to 1, and the animation was playing behind
(i checked if the time elapsed to get in my OnAnimationCompleted eventHandler matched with the transition Duration)
so i've created a second animation on the TargetElement opacity with 2 DiscreteDoubleKeyFrames to do the trick and now it works ^^
Maybe the Storyboard thing could work if i add the namespace in the PropertyPath but i have no time to test it so give it a try if you want, and update the post ^^.