I have a cell where the bottom 10px ish is used as a seperator. I want to make the UITableViewRowAction to be the same height as the inner view without the seperator but swift does not seem to support this kind of functionality..
Is there any way to do this?
you can change the size of the Delete button by
-(void)didTransitionToState:(UITableViewCellStateMask)state
{
[super didTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask)
{
UIView *deleteButton = [self deleteButtonSubview:self];
if (deleteButton)
{
CGRect frame = deleteButton.frame;
frame.origin.y = 4;
frame.size.height = frame.size.height-8;
/*
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
//use your desired size for iPad
frame.size.height = 62;
frame.size.width = 80;
}
else
{
//use your desired size for iPhone
frame.size.height = 52;
frame.size.width = 80;
}
*/
deleteButton.frame = frame;
}
}
}
- (UIView *)deleteButtonSubview:(UIView *)view
{
if ([NSStringFromClass([view class]) rangeOfString:#"Delete"].location != NSNotFound) {
return view;
}
for (UIView *subview in view.subviews) {
UIView *deleteButton = [self deleteButtonSubview:subview];
[deleteButton setBackgroundColor:[UIColor whiteColor]];
if (deleteButton) {
return deleteButton;
}
}
return nil;
}
Related
I'm trying to resize UITableView cell's delete button with this code but for some reason, the x & y are working fine but i'm unable to change the height & width of the delete button. I'm using this code in my custom UITableViewCell class and everything works fine excel the width & hight of the "Delete" button.
what am i missing here?
- (void)layoutSubviews
{
[super layoutSubviews];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0f];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 250;
newFrame.origin.y = 47;
newFrame.size.height = 30;
newFrame.size.width = 50;
deleteButtonView.frame = newFrame;
subview.frame = newFrame;
}
}
[UIView commitAnimations];}
use this code...
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect f = deleteButtonView.frame;
f.origin.x = 250;
f.origin.y = 47;
f.size.width = 30;
f.size.height = 50;
CGRect sf = self.frame;
sf.size.width = 100;
sf.size.height = 100;
deleteButtonView.frame = f;
self.frame = sf;
}
see another answer from this link...iphone-uitableview-delete-button
Use this code in your custom Cell class
-(void)layoutSubviews
{
NSMutableArray *subviews = [self.subviews mutableCopy];
UIView *subV = subviews[0];
[subviews removeObjectAtIndex:0];
CGRect f = subV.frame;
f.size.height = 70; // Here you set height of Delete button
subV.frame = f;
}
Find the "UITableViewCellDeleteConfirmationView" in the UITableviewCell for changing the delete button height.
Use this code in your custom cell class
- (void)layoutSubviews {
[super layoutSubviews];
NSMutableArray *subviews = [self.subviews mutableCopy];
while (subviews.count > 0)
{
UIView *subV = subviews[0];
[subviews removeObjectAtIndex:0];
if ([NSStringFromClass([subV class])isEqualToString:#"UITableViewCellDeleteConfirmationView"])//Here you select the subView of delete button {
UIView *deleteButtonView = (UIView *)[self.subviews objectAtIndex:0];
CGRect buttonFrame = deleteButtonView.frame;
buttonFrame.origin.x = deleteButtonView.frame.origin.x;
buttonFrame.origin.y = deleteButtonView.frame.origin.y;
buttonFrame.size.width = deleteButtonView.frame.size.width;
buttonFrame.size.height = 70; //Here you set the height
deleteButtonView.frame = buttonFrame;
}
}
}
You can also do it using constraints ( working on iOS 8.x +).
That way the animations (delete button animation especially) stay neat / no UI glitch.
In your UITableViewCell subclass :
Declare a weak property in your class anonymous category :
#property (weak, nonatomic) UIView *lastDeleteConfirmationView;
Disable translating of autoresizing mask constraints and add your own constraints :
- (void)layoutSubviews {
[super layoutSubviews];
[self addConstraintsToCellDeleteConfirmationView];
}
- (void)addConstraintsToCellDeleteConfirmationView {
UIView *deleteConfirmationView = nil;
for (UIView *subview in self.subviews) {
if ([NSStringFromClass(subview.class) isEqualToString:#"UITableViewCellDeleteConfirmationView"]) {
deleteConfirmationView = subview;
break;
}
}
if (deleteConfirmationView && self.lastDeleteConfirmationView != deleteConfirmationView) {
self.lastDeleteConfirmationView = deleteConfirmationView;
self.lastDeleteConfirmationView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint constraintWithItem:self.customBackgroundView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.lastDeleteConfirmationView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f].active = YES;
[NSLayoutConstraint constraintWithItem:self.customBackgroundView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.lastDeleteConfirmationView attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f].active = YES;
[NSLayoutConstraint constraintWithItem:self.lastDeleteConfirmationView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.lastDeleteConfirmationView.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f].active = YES;
}
}
SWIFT
override func layoutSubviews() in CustomTableViewCell: UITableViewCell
override func layoutSubviews() {
for subview in self.subviews {
if String(describing: type(of: subview.self)).isEqualToString("UITableViewCellDeleteConfirmationView") {
var newFrame = subview.frame
newFrame.origin.y = 10
newFrame.size.height = 60
subview.frame = newFrame
}
}
}
I have this code that works perfectly on an iPad2 but it scales wrong on a Retina iPad.
I executed the app with no change on both iPads and the behaviour is totally different.
On the Retina iPad the images come back to the original position and the transform doesn't take place.
The code takes a group of views, add them to a temporal view, resize the temporal view and them add those views back, so I can resize all of them at the same time.
- (IBAction)scaleParts:(UIPinchGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
self.tempCanvasView = [[UIView alloc] initWithFrame:self.canvas.bounds];
self.tempCanvasView.backgroundColor = [UIColor redColor];
for (UIView *view in [self.canvas subviews]) {
CGRect currentFrame = view.bounds;
CGRect newFrame = [view convertRect:currentFrame toView:self.tempCanvasView];
view.bounds = newFrame;
[self.tempCanvasView addSubview:view];
}
[self.canvas addSubview:self.tempCanvasView];
} else if (sender.state == UIGestureRecognizerStateChanged) {
self.tempCanvasView.transform = CGAffineTransformScale(self.tempCanvasView.transform, sender.scale, sender.scale);
sender.scale = 1.0;
} else if (sender.state == UIGestureRecognizerStateEnded) {
for (UIView *view in [self.tempCanvasView subviews]) {
CGRect currentFrame = view.bounds;
CGRect newFrame = [view convertRect:currentFrame toView:self.canvas];
view.frame = newFrame;
[self.canvas addSubview:view];
}
[self.tempCanvasView removeFromSuperview];
self.tempCanvasView = nil;
}
}
Maybe you need to detect which screen type the app is using (scale=1 for iPad and 2 for iPadRetina).
CGFloat scale = [[UIScreen mainScreen] scale];
after that..
if (scale==1) {
//code from above
} else {
//code from above with small modification
}
Here is a correct method to do it:
SWIFT:
extension UIView {
func convertRectCorrectly(rect: CGRect, toView view: UIView) -> CGRect {
if UIScreen.mainScreen().scale == 1 {
return self.convertRect(rect, toView: view)
}
else if self == view {
return rect
}
else {
var rectInParent = self.convertRect(rect, toView: self.superview)
rectInParent.origin.x /= UIScreen.mainScreen().scale
rectInParent.origin.y /= UIScreen.mainScreen().scale
let superViewRect = self.superview!.convertRectCorrectly(self.superview!.frame, toView: view)
rectInParent.origin.x += superViewRect.origin.x
rectInParent.origin.y += superViewRect.origin.y
return rectInParent
}
}
}
I have a problem in scaling the uiimageview which is placed inside the uiscrollview. I have googled and checked all the questions related to my problem in StackOverflow as well. I tried all the answers that are posted in the StackOverflow also. Nothing worked for me.
First I am placing the uiimageview inside uiscrollview in nib file and I am taking the image from Camera roll and filling the image view. Then I am using uirotationgesturerecognizer to rotate the image.
Here is the code that I am trying to do.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%#",[[UIDevice currentDevice] model]);
// Do any additional setup after loading the view, typically from a nib.
self.imagePicker = [[[UIImagePickerController alloc] init] autorelease];
self.picChosenImageView.layer.shouldRasterize = YES;
self.picChosenImageView.layer.rasterizationScale = [UIScreen mainScreen].scale;
self.picChosenImageView.layer.contents = (id)[UIImage imageNamed:#"test"].CGImage;
self.picChosenImageView.layer.shadowColor = [UIColor blackColor].CGColor;
self.picChosenImageView.layer.shadowOpacity = 0.8f;
self.picChosenImageView.layer.shadowRadius = 8;
self.picChosenImageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.picChosenImageView.bounds].CGPath;
UIRotationGestureRecognizer *rotationRecognizer = [[[UIRotationGestureRecognizer alloc]initWithTarget:self
action:#selector(handleRotate:)] autorelease];
rotationRecognizer.delegate = self;
[self.picChosenImageView addGestureRecognizer:rotationRecognizer];
self.containerView.delegate = self;
self.containerView.contentSize = self.picChosenImageView.layer.frame.size;
self.containerView.maximumZoomScale = 4.0f;
self.containerView.minimumZoomScale = 1.0f;
angle = 0.0f;
useRotation = 0.0;
isRotationStarted=FALSE;
isZoomingStarted = FALSE;
}
-(void)lockZoom
{
maximumZoomScale = self.containerView.maximumZoomScale;
minimumZoomScale = self.containerView.minimumZoomScale;
self.containerView.maximumZoomScale = 1.0;
self.containerView.minimumZoomScale = 1.0;
self.containerView.clipsToBounds = false;
self.containerView.scrollEnabled = false;
}
-(void)unlockZoom
{
self.containerView.maximumZoomScale = maximumZoomScale;
self.containerView.minimumZoomScale = minimumZoomScale;
self.containerView.clipsToBounds = true;
self.containerView.scrollEnabled = true;
}
#pragma mark - ScrollView delegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.picChosenImageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
CGRect frame = self.picChosenImageView.frame;
frame.origin = CGPointZero;
self.picChosenImageView.frame = frame;
//self.picChosenImageView.transform = prevTransform;
}
-(void) scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
if(!isZoomingStarted)
{
self.picChosenImageView.transform = CGAffineTransformRotate(self.picChosenImageView.transform, angle);
NSLog(#"The zooming started");
isZoomingStarted = TRUE;
CGSize contentSize = self.containerView.bounds.size;
CGRect contentFrame = self.containerView.bounds;
NSLog(#"frame on start: %#", NSStringFromCGRect(contentFrame));
NSLog(#"size on start: %#", NSStringFromCGSize(contentSize));
//prevTransform = self.picChosenImageView.transform;
}
}
-(void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
if(isZoomingStarted)
{
self.picChosenImageView.transform = CGAffineTransformRotate(self.picChosenImageView.transform, angle);
isZoomingStarted = FALSE;
CGSize contentSize = self.containerView.contentSize;
CGRect contentFrame = self.containerView.bounds;
NSLog(#"frame on end: %#", NSStringFromCGRect(contentFrame));
NSLog(#"size on end: %#", NSStringFromCGSize(contentSize));
}
}
#pragma mark - GestureRecognizer methods
- (void) handleRotate:(UIRotationGestureRecognizer *)recognizer
{
if(isZoomingStarted == FALSE)
{
if([recognizer state] == UIGestureRecognizerStateBegan)
{
angle = 0.0f;
[self lockZoom];
}
useRotation+= recognizer.rotation;
while( useRotation < -M_PI )
{
useRotation += M_PI*2;
}
while( useRotation > M_PI )
{
useRotation -= M_PI*2;
}
NSLog(#"The rotated value is %f",RADIANS_TO_DEGREES(useRotation));
self.picChosenImageView.transform = CGAffineTransformRotate([self.picChosenImageView transform],
recognizer.rotation);
[recognizer setRotation:0];
if([recognizer state] == UIGestureRecognizerStateEnded)
{
angle = useRotation;
useRotation = 0.0f;
isRotationStarted = FALSE;
self.containerView.hidden = NO;
//prevTransform = self.picChosenImageView.transform;
[self unlockZoom];
}
}
}
My problem is, I am able to successfully do a zoom in and zoom out. I am able to rotate the uiimageview as I wanted to. After rotating the uiimageview to a certain angle, and when I am trying to zoom in, the imageview gets back to the original position (rotate itself back to zero degree) and then the zooming happens. I want to retain the rotation and also zoom. I tried saving the previous transform and assign in back scrollDidzoom and scrollDidBegin delegate methods. None worked. Please help me to spot my mistake which I am overlooking.
try using CGAffineTransformScale instead of just resizing the frame for zooming:
anImage.transform = CGAffineTransformScale(anImage.transform, 2.0, 2.0);
changing the transform for scaling might fix your rotation issue.
hope this helps.
I had the same problem. UIScrollView is taking control over UIImageView and it is using transform without rotation.
So I do not give image reference to scroll and I have added UIPinchGestureRecognizer for scaling.
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return nil
}
Dragging is still working :)
// viewDidLoad
var pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(pinchRecogniezed))
scrollView.addGestureRecognizer(pinchGestureRecognizer)
func pinchRecogniezed(sender: UIPinchGestureRecognizer) {
if sender.state == .Began || sender.state == .Changed {
let scale = sender.scale
imageView.transform = CGAffineTransformScale(imageView.transform, scale, scale)
sender.scale = 1
}
}
I have a question in scroll view.
Right now I wrote a sample about image gallery with scroll view. I have plenty of images added into a scroll view. Each time, it display 3 images, the question is how can measure the scrolling properly. For example: the minimum each scroll is moving 1 image. Right now, I think each time I scroll, the minimum images moving are 3. That make me can't stop at the right image I want to see.
Below is the code.
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scroll subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scroll setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scroll bounds].size.height)];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[scroll setBackgroundColor:[UIColor blackColor]];
[scroll setCanCancelContentTouches:NO];
scroll.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scroll.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scroll.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scroll.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scroll addSubview:imageView];
[imageView release];
}
[self layoutScrollImages];
}
Use this code......
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(scroll.contentOffset.y> 320)
{
int y = scrollView.contentOffset.y;
y = y/3;
[scrollView setContentOffset:CGPointMake(0, y)];
}
}
Hope, this will help you...Chill
Subclass the content view and overwrite this function:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([self pointInside:point withEvent:event]) {
if ([[self subviews] count] > 0) {
//force return of first child, if exists
return [[self subviews] objectAtIndex:0];
} else {
return self;
}
}
return nil; }
See detail at https://github.com/taufikobet/ScrollViewCustomPaging.
I have an array of Image URl's from that array i have displayed my Images in Scrollview because i want to take the advantage of Paging and zooming so what should i do to achieve this task?suppose my array contains 10 URL then by each time scrolling i should get different image and i could also performing Zooming-In and Zooming-Out any of the 10 Images so please give me some guidelines to achieve my task.Thanks in Advance.
Try this
- (void)setCurrentPage:(NSUInteger)page {
if (page == offsetX)
return;
offsetX = page;
// in a real app, this would be a good place to instantiate more view controllers -- see SDK examples
}
- (CGSize)pageSize {
CGSize pageSize = scrollView1.frame.size;
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
return CGSizeMake(pageSize.height, pageSize.width);
else
return pageSize;
}
- (void)setPagingMode {
// reposition pages side by side, add them back to the view
CGSize pageSize = [self pageSize];
NSUInteger page = 0;
for (UIView *view in imgViewArray) {
if (!view.superview)
[scrollView1 addSubview:view];
view.frame = CGRectMake(pageSize.width * page++, 0, pageSize.width, pageSize.height);
}
scrollView1.pagingEnabled = YES;
scrollView1.showsVerticalScrollIndicator = scrollView1.showsHorizontalScrollIndicator = NO;
scrollView1.contentSize = CGSizeMake(pageSize.width * [imgViewArray count], pageSize.height);
scrollView1.contentOffset = CGPointMake(pageSize.width * offsetX, 0);
scrollViewMode = ScrollViewModePaging;
}
- (void)setZoomingMode {
NSLog(#"setZoomingMode");
scrollViewMode = ScrollViewModeZooming; // has to be set early, or else currentPage will be mistakenly reset by scrollViewDidScroll
// hide all pages except the current one
NSUInteger page = 0;
for (UIView *view in imgViewArray)
if (offsetX != page++)
[view removeFromSuperview];
scrollView1.pagingEnabled = NO;
scrollView1.showsVerticalScrollIndicator = scrollView1.showsHorizontalScrollIndicator = YES;
pendingOffsetDelta = scrollView1.contentOffset.x;
scrollView1.bouncesZoom = YES;
}
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// offsetX=(aScrollView.contentOffset.x)/768;
//NSLog(#"Page No:%d",offsetX);
if (scrollViewMode == ScrollViewModePaging)
[self setCurrentPage:roundf(scrollView1.contentOffset.x / [self pageSize].width)];
}
else
{
//offsetX=(aScrollView.contentOffset.x)/320;
//NSLog(#"Page No:%d",offsetX);
if (scrollViewMode == ScrollViewModePaging)
[self setCurrentPage:roundf(scrollView1.contentOffset.x / [self pageSize].width)];
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)aScrollView
{
NSLog(#"viewForZoomingInScrollView");
if (scrollViewMode != ScrollViewModeZooming)
[self setZoomingMode];
return [imgViewArray objectAtIndex:offsetX];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale:(float)scale {
NSLog(#"scrollViewDidEndZooming");
if (scrollView1.zoomScale == scrollView1.minimumZoomScale)
[self setPagingMode];
else if (pendingOffsetDelta > 0) {
UIView *view = [imgViewArray objectAtIndex:offsetX];
view.center = CGPointMake(view.center.x - pendingOffsetDelta, view.center.y);
CGSize pageSize = [self pageSize];
scrollView1.contentOffset = CGPointMake(scrollView1.contentOffset.x - pendingOffsetDelta, scrollView1.contentOffset.y);
scrollView1.contentSize = CGSizeMake(pageSize.width * scrollView1.zoomScale, pageSize.height * scrollView1.zoomScale);
pendingOffsetDelta = 0;
}
}