Moving a cell using CGRectOffset - what am I doing wrong? - ios

I stumbled upon this fantastic library for implementing table view cell sliding, but there's a few minor differences between what it offers and what I'm looking to have, so I'm continuing with my implementation.
The way the developer moved the table view cells was creative, I thought, in that he used CGRectOffset() to add almost padding to the sides of the cell as it moved to look like it was moving.
I want to do something similar for mine, as it seems like the easiest way to accomplish this. However, when I do the following, nothing happens to the cell:
(Just an example):
CGFloat offset = 11;
self.contentView.frame = CGRectOffset(self.contentView.bounds, offset, 0);
I set a breakpoint there, so it's indeed being called when I pan across the cell (it's in the gesture recognizer method). Yet after it gets called, the cell looks identical in position.
And I have this at the beginning, similar to how he set up the view:
- (void)awakeFromNib {
[super awakeFromNib];
self.contentView.backgroundColor = [UIColor whiteColor];
UIView *backgroundView = [[UIView alloc] initWithFrame:self.contentView.frame];
backgroundView.backgroundColor = [UIColor whiteColor];
self.backgroundView = backgroundView;
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pannedCell:)];
panGestureRecognizer.delegate = self;
[self addGestureRecognizer:panGestureRecognizer];
}
So I'm not sure exactly why it's not working. Does anyone have any ideas?

Related

Performance issue with UIVisualEffectView in UITableViewCell

I have UITableView with 10 big images like Instagram and i have some blurview on that images. I add my visualeffects UITableViewCell like that;
_blurButtonEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_visualButtonEffectView = [[UIVisualEffectView alloc] initWithEffect:_blurButtonEffect];
_visualButtonEffectView.layer.cornerRadius = 10.0f;
_visualEmojiEffectView = [[UIVisualEffectView alloc] initWithEffect:_blurButtonEffect];
_visualEmojiEffectView.layer.cornerRadius = 24.0f;
_visualButtonEffectView.layer.masksToBounds = YES;
_visualEmojiEffectView.layer.masksToBounds = YES;
_visualButtonEffectView.frame = CGRectMake(20.0f, _button.frame.origin.y + 7.0f, 48.0f, 48.0f);
_visualEmojiEffectView.frame = CGRectMake(_emoji.frame.origin.x - 4.0f, _button.frame.origin.y + 22.0f, ([UIScreen mainScreen].bounds.size.width/2) - 25.0f, 30.0f);
If button title is null, i show _visualEmojiEffectView and hide _visualButtonEffectView. Otherwise _visualButtonEffectView is always shown. While i'm scrolling my UITableView, performance is perfect but this blur effects shown so annoying, they seems like flashing with every scroll movement and touches. I can block this with this in cell;
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
If i'm rasterize my cell like that, blur effect works perfect but scrolling performance is awful even on iPhone 6. What is the correct way to configure UIBlurEffectView with UITableViewCell?
I know it is too late to reply but still i hope this helps someone. You can give a white background colour to the visual effect view with a very low alpha. Something like this:
[_visualButtonEffectView setBackgroundColor:[UIColor colorWithWhite:1.0 alpha:0.2]];
You may also try using UIToolbar instead of a visual effect view. It does not give exactly the same effect but will still be good enough.

Is UICollectionView.backgroundView broken

I'm writing something relatively simple, or so I thought.
Firstly, the code, for which I'm trying to place an image on the background of the UICollectionView if there are no results returned from my server. The image is 200 by 200:
UIView *myView = [[UIView alloc] initWithFrame:self.view.bounds];
CGRect myViewSpace = self.view.bounds;
CGFloat myX = (myViewSpace.size.width /2.0) - 100;
CGFloat myY = (myViewSpace.size.height /2.0) - 100;
UIImageView *imView = [[UIImageView alloc] initWithFrame:CGRectMake(myX, myY, 200, 200)];
imView.image = [UIImage imageNamed:#"imNotHome"];
[myView addSubview:imView];
myCollectionView.backgroundView = myView;
Once there are results, I want to be able to remove it.
I thought it'd be as simple as placing the following, before I reloaded the UICollectionView:
[myCollectionView.backgroundView removeFromSuperview];
However, it appears to be doing nothing.
Am I missing something?
Thanks in advance!
It should be done this way instead:
myCollectionView.backgroundView = nil;
Explanation: You should unset the UICollectionView's background in the same way as you set it. You didn't set it by manipulating the view hierarchy, but by setting the background property. You did call addSubview in the previous line, but that was to add a subview to your background view, not to add the background view itself.
Edit:
There is a very good article about this UICollectionView bug here:
http://blog.spacemanlabs.com/2013/11/uicollectionviews-backgroundview-property-is-horribly-broken/
The solution the author gives is to reset the background to an empty opaque view:
UIView *blankView = [UIView new];
blankView.backgroundColor = [UIColor whiteColor];
[myCollectionView.backgroundView removeFromSuperview];
myCollectionView.backgroundView = blankView;
Also, the author recommends not using the backgroundView property at all but doing it yourself:
Frankly, I think the best solution is to just ignore the backgroundView property all together. Instead, make the collection view’s background clear, and implement your own backgroundView; just throw a view behind the collection view.

iOS - UIView Always on Front without BringSubviewToFront

Can I have some UIView which will always appear on top in iOS?
There are lots of addSubview in my project but I need to have one small view which will always appear. SO is there any other option than
[self.view bringSubViewToFront:myView];
Thanks
One more option (especially if you want to overlap several screens, with logo for example) - separate UIWindow. Use windowLevel to set the level of new window.
UILabel *devLabel = [UILabel new];
devLabel.text = #" DEV ";
devLabel.font = [UIFont systemFontOfSize:10];
devLabel.textColor = [UIColor grayColor];
[devLabel sizeToFit];
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
static UIWindow *notificationWindow;
notificationWindow = [[UIWindow alloc] initWithFrame:
CGRectMake(screenSize.width - devLabel.width, screenSize.height - devLabel.height,
devLabel.width, devLabel.height)];
notificationWindow.backgroundColor = [UIColor clearColor];
notificationWindow.userInteractionEnabled = NO;
notificationWindow.windowLevel = UIWindowLevelStatusBar;
notificationWindow.rootViewController = [UIViewController new];
[notificationWindow.rootViewController.view addSubview:devLabel];
notificationWindow.hidden = NO;
Another option is set layer.zPosition of your UIView.
You need to add
#import <QuartzCore/QuartzCore.h>
Framework to your .m file.
And set such like
myCustomView.layer.zPosition = 101;// set maximum value as per your requirement.
For more information about layer.zPosition read this documentation.
Discussion
The default value of this property is 0. Changing the value of this property changes the the front-to-back ordering of layers onscreen. This can affect the visibility of layers whose frame rectangles overlap.
The other option is to add other subviews below this always-on-top subview. For example:
[self.view insertSubview:subview belowSubview:_topSubview];
There's no solution with Interface Builder if you search for this kind. It should be done programmatically. If you don't want to use bringSubviewToFront: everytime, just insert other subviews below this one.
Many times your view did not appear in viewDidLoad or, if your view comes from parentViewController (for example in many transitions like modal segue..) your can see parentViewController only in viewDidAppear so:
Try to put bringSubviewToFront in :
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.view bringSubViewToFront:myView];
// or if your view is attached in parentViewController
[self.parentViewController.view bringSubViewToFront:myView];
}
Good luck!

Why arent the views being added to this UIAnimator?

Im adding views to an animator like so:
-(void)drawCellLikeViews{
//2. Add Animator
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];
//Alloc array
viewsArray = [[NSMutableArray alloc] initWithCapacity:6];
for (int numberOfViews = 0; numberOfViews < 5; numberOfViews++) {
//Create views
UIView* cell = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 70)];
cell.backgroundColor = [UIColor grayColor];
[self addSubview:cell];
[viewsArray addObject:cell];
}
//3. Add Gravity
_gravity = [[UIGravityBehavior alloc] initWithItems:viewsArray];
[_animator addBehavior:_gravity];
//4. Add boundaries
_collision = [[UICollisionBehavior alloc] initWithItems:viewsArray];
_collision.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_collision];
//8. Add ItemProperties' Behaviors
UIDynamicItemBehavior* itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:viewsArray];
itemBehaviour.elasticity = 0.6;
//9. itemBehaviour.action = ^{};
[_animator addBehavior:itemBehaviour];
NSLog(#"viewcount %d", [[self subviews] count]);
}
I only see one drop down to the bottom.
#HalR is correct—your views are being added to the animator; they're just all being added at the same time with the same starting attributes, so they will all behave in exactly the same way and appear as one item. And yes, by default, the collision behavior's mode is UICollisionBehaviorModeEverything, meaning its items should collide with each other and with the boundaries. Yet, by implying UICollisionBehaviorModeEverything and placing all of the items on top of each other, you've created an impossible scenario wherein you've explicitly told the edges of each item to overlap, but you've told the animator that they're not allowed to overlap. The animator's behavior at that point is undefined—I think it just ignores whatever physics rule you've manually broken, but it can get much weirder than that. In WWDC 2013 Session 206 (Getting Started with UIKit Dynamics), Apple at one point says "don't expect the impossible" saying that "you can create setups which don't have solutions" and showing overlapping items with collision behaviors set as an example. In other words, they saw this coming, and they just don't want you to do it. ;)
The way to make this work, of course, would just be to give each of the items a starting position that doesn't overlap with other items' starting positions, or to add them all to where you're adding them now, only a few seconds apart from each other so the last one can fall out of the way.

Shadow in separate view from UIImage for dynamic adjustments

I would like to obtain this effect (http://stackoverflow.com/questions/7023271/how-to-adjust-drop-shadow-dynamically-during-an-uiimageview-rotation) but from a more complex image than just a red square ! If the link ever gets broken, it's a about how to adjust drop shadow dynamically during an UIImageView rotation.
So I tried implementing something but I just can't get the shadow in a separate layer... Here is my code, very simple, but doesn't work:
// here is my code
- (void)viewDidLoad {
[super viewDidLoad];
testView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"handNoShadow.png"]];
testViewShadow = [[UIView alloc] initWithFrame:testView.frame];
testViewShadow.layer.shadowPath = [[testView layer] shadowPath];
testViewShadow.layer.shadowOpacity = 1.0;
testViewShadow.layer.shadowOffset = CGSizeMake(10, 10);
testViewShadow.layer.shadowRadius = 5.0;
[self.view addSubview:testViewShadow];
[self.view addSubview:testView];
}
PS: i did #import
I do get an image but no shadow... =(
Any lead, help, code, link... is welcome !
Thanks
possible cause:
your testViewShadow.clipToBounds property is set to YES (should be NO)
your testViewShadow do the drawing of the shadow correctly but another UIView is on top and mask it. Check your Z order. Either the order in Storyboard/Nib file (or the order you added the subviews programmatically). Last in the list (or last one added) is on top. For my app I had to put the UIView that need a shadow last so that no other view mask it.

Resources