I have a uitableview with four static cells
First cell has a uitextview
second and third and regular cells
Fourth cell has uitextview
I need first and fourth cell to grow and shrink based on the content size. Fourth cell is going to have much larger text, so whole page should scroll for that.
Any ideas how to do that? Thanks.
D.
You can use :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) {
// Your code to find height of the text whic will display in UITextView.
}else{
// your default cell height
}
}
Hope this will help you.
All the best !!!
Related
I want to have the table view cell expand and show the buttons that I have laid out below the visible view when the cell isn't selected. So far I have managed to expand the cell so that the entire view shows with the buttons, but there is one major problem with this....
The buttons that are supposed to be revealed only when the cell is selected always appear in the table, and the table view looks really weird becuase for each cell there are buttons overlapping the next cell which were supposed to be hidden!
I have tired making a subclass of the cell, but I am stuck because when I override the setSelected method to show the button, all the buttons from all the cells show up, not just the one I clicked, Ill provide my code below.
I there an easier way to show the buttons without using a subclass? And if not how could I use the subclass in a way that wouldn't show all the buttons for all the cells?
Cell Subclass (.m file)
- (void)awakeFromNib {
// Initialization code
editHidden.hidden = YES;
removeHidden.hidden = YES;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
editHidden.hidden = NO;
removeHidden.hidden = NO;
// Configure the view for the selected state
}
Your table view delegate needs to implement tableView:heightForRowAtIndexPath:. Implement this method to return the correct height for your cell given the state that it is in (collapsed or expanded). When it comes time to expand your cell you should update your state and call [tableView beginUpdates]; [tableView endUpdates]; to have it recalculate and relayout the tableview.
The issue I am having is this:
1) Some of the preview thumbnails do not show, but displays the full picture when clicked as it's meant to when clicked. This is the main code that implements the thumbnails:
` NSString *imageToLoad = [NSString stringWithFormat:#"%d.JPG", indexPath.row];
cell.image.image = [UIImage imageNamed:imageToLoad];
return cell;`
So the '#"%d.JPG",' receives the files as need.
2) Also, I've tried in the properties panel to change the spacings so the pictures are not right against the edge, seems to have no effect, any thoughts on this?
Many thanks :)
To answer your first question, you can use placeholder image to show.
To answer your second question this UICollectionViewFlowLayoutDelegate method will help you..
- (CGFloat)collectionView:(PSUICollectionView *)collectionView layout:(PSUICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 10; // This is the minimum inter item spacing, can be more
}
One more if you need more space to arrange your cells adjust the edgeInsets also.
So I have a UICollectionView with custom UIViews for each cell. The UIView takes up the whole screen and you can horizontally navigate to each of the 4 different UIView/cells. This all works fine and uses a pager to indicate which page of the collectionview you are on.
I have looked around google and the like to see if I could get it to loop back to the beginning after you navigate passed the last cell. So for example:
I start at the 3rd cell, navigate to the 4th, then when i swipe to the right, it will go back to the first cell (pager will reflect that you are on the first page) and continue on from there.
Is this easy to do? Or am I missing something?
Thanks,
Jake
You only need 3 UIViews, to hold the image to the left of your current view, the image to the right of the current view, and the middle view, the one that is currently onscreen.
So lets say we have UIImages A B C D and UIViews 1 2 and 3
We are looking at View 2, image B. Page left will take us to image A, page right to image C.
As you swipe left/ page right, view 3 becomes the onscreen view with image C. When paging comes to rest, you swap the views contents around so the user is actually looking at the middle UIView2 again, with image C. View 1 has image B, view 3 has image D.
Scroll right again, and do the same shuffle. Now you have
View 1 -> image C
View 2 -> image D
View 3 -> image A
Next page right
View 1 -> image D
View 2 -> image A
View 3 -> image B
so on, ad infinitum in either direction
There is a nice WWDC video on this subject from 2011. Its worth digging out. It's the UIScrollView demo video (Documentation as PDF) You don't need Collection Views to do this, although there is no reason why you shouldn't...
Alright ready for this hotness?
So in my main view controller's viewDidLoad I identify the views to load into the uicollectionview cells in an array:
NSArray *vcs = [#"view5", #"view1", #"view2", #"view3", #"view4", #"view5", #"view1"]
I also set our pagecontrol count to:
self.pageControl.numberOfPages = vcs.count - 2; // for the fake first and last cells
I then instantiate the viewcontrollers in the main view controller's viewDidLoad as well as set the alpha for the collectionview to 0. Then in our scrollViewDidEndDecelerating I handle the Carousel (go from last cell to first and first cell to last) and updating the pageControl to reflect the "real" page number.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// Snaps into the cell
CGFloat pageWidth = scrollView.frame.size.width;
float fractionalPage = scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page - 1; // because our first cell is the last cell for animation purposes only
// Carousel from first to last and last to first while updating pagecontrol
if (page == 0) {
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:self.activeGaugeClusters.count - 2 inSection:0]
atScrollPosition:UICollectionViewScrollPositionLeft
animated:NO];
// Set our pagecontrol circles to the appropriate page indicator
self.pageControl.currentPage = self.activeGaugeClusters.count - 2;
} else if (page == self.activeGaugeClusters.count -1) {
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]
atScrollPosition:UICollectionViewScrollPositionLeft
animated:NO];
self.pageControl.currentPage = 0;
}
}
Then in the collectionview implementation I do the following:
numberOfItemsInSection = vcs.count
and viewDidAppear for loading the first cell (whether it is the cell at indexPath.row == 1 or 2 or 3... (1 being the first real page not 0)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:self.lastGaugePanel inSection:0]
atScrollPosition:UICollectionViewScrollPositionLeft
animated:NO];
self.pageControl.currentPage = self.lastGaugePanel - 1;
[UIView animateWithDuration:0.5 animations:^{
self.collectionView.alpha = 1.0;
}];
}
I think that about sums it up. The rest of the implementations for both the main vc and the collectionview are standard. So now I have a collection view that loads up other views and their VCs that each have their own animation or whatever. I save the indexPath.row to NSUserDefaults so that the cell that I was in when I leave is the first cell to show on the next load.
Hopes this helps someone, I know it did for me, unfortunately the use of 3rd party libraries was discouraged so I had to build this bad boy up (with help from #He Was, thanks again!)
I've a vertical NSSplitView, the bottom subview contains a custom view (eg NSView) and a NSTextView.
The NSView contains inside it two NSButtons.
When I resize the splitView, making it smaller, the NSView containing the buttons is resized, too.
I don't want this behavior.
To better explain my problem please view the attached image.
Image 1: the window at application startup, everything is ok
Image 2: I've resized making smaller the split view, only a little part of buttons is visible
Image 3: I've enlarged again the split view but as you can see the NSView remains smaller and buttons are no longer visible (if I resize the splitView to bottom the NSView 'disappears')
This is a vicious problem that's based on the legacy workings of Cocoa views. The best solution I've seen is to constrain the minimum dimension of any portion of the split view. If the subviews never collapse, their metrics don't cross into another dimension and they should re-enlarge just fine.
To do this, set up a delegate for your split view, which will implement - splitView:constrainMaxCoordinate:ofSubviewAt:. The split view will call your delegate method hoping it can leave the max divider position at the height of the split view (passing this in as the second argument), but you can simply subtract some quantity from that value (say, 60) to return it as the minimum height for the bottom view.
- (CGFloat)splitView:(NSSplitView *)aSplitView
constrainMaxCoordinate:(CGFloat)proposedMin
ofSubviewAt:(NSInteger)dividerIndex {
return proposedMin - 60;
}
Of course, you'll probably want to do more checking in this method to make sure you're talking about the right split view, and the right subview, to avoid overreaching effects, but this is the basic idea.
(See also this fabulicious article on the subject.)
Constraining the divider position did not help in my case, as I'm animating the subviews and subviews can be collapsed.
I managed to achieve an acceptable solution by implementing the splitView delegate method -splitviewWillResizeSubviews: (means, you have to connect the delegate property from the split view to your controller in IB or in code) to maintain a minimum width by setting the subview to hidden instead of shrinking it to zero:
- (void)splitViewWillResizeSubviews:(NSNotification *)notification {
NSUInteger divider = [[[notification userInfo] valueForKey:#"NSSplitViewDividerIndex"] intValue];
NSView *subview = nil;
if(divider == SPLITVIEW_DIVIDER_SIDEBAR) {
subview = (NSView*)[self.splitView.subviews objectAtIndex:SPLITVIEW_SIDEBAR_INDEX];
}
if(subview) {
if(subview.frame.size.width < SPLITVIEW_MINIMUM_SIDEBAR_WIDTH) {
CGRect correctedFrame = subview.frame;
correctedFrame.size.width = SPLITVIEW_MINIMUM_SIDEBAR_WIDTH;
subview.frame = correctedFrame;
subview.hidden = YES;
} else {
subview.hidden = NO;
}
}
}
I have implemented a view-based NSOutlineView in my project. I am using floating group rows. Now, I would like to have this NSOutlineView look basically like the Finder list-view (CMD-2) when it is in the "arranged-by" layout (e.g. "by kind": CTRL-CMD-2). That means, the top-most group row should display the column titles and as soon as the next lower group row is starting to nudge the previous one out of the view, the column titles fade in on the second group row (I hope this makes sense).
Is there any out-of-the-box way to achieve this? So far I have successfully subclassed NSTableCellView to show the columns' titles, however, I cannot get the fade-in to work as I cannot seem to find out the position of the group row in relation to the floating one above it.
Regards,
Michael
I've found a possible way to achieve what I want. In my custom NSTableCellView's drawRect: method, it's of course possibly in a nasty way to find out the view's position relative to the enclosing NSClipView. The relevant code:
- (void)drawRect:(NSRect)dirtyRect {
// _isGroupView is a member variable which has to be set previously
// (usually in setObjectValue:) in order for us to know if we're a
// group row or not.
if (_isGroupView) {
// This is the nasty party:
NSClipView *clipView = (NSClipView*)self.superview.superview.superview;
if (![clipView isKindOfClass:[NSClipView class]]) {
NSLog(#"Error: something is wrong with the scrollbar view hierarchy.");
return;
}
NSRect clipRect = [clipView documentVisibleRect];
CGFloat distanceToTop = self.superview.frame.origin.y - clipRect.origin.y;
if (self.superview.frame.origin.y - clipRect.origin.y < self.frame.size.height) {
// This means, that this NSTableCellView is currently pushing the
// view above it out of the frame.
CGFloat alpha = distanceToTop / self.frame.size.height;
NSColor *blendColor = [[NSColor blackColor] blendedColorWithFraction:alpha ofColor:[NSColor whiteColor]];
// ...
// do stuff with blendColor
// ...
// blendColor should now be the appropriate color for the wanted
// "fade in" effect.
//
}
}
}
I hope this makes sense ;-). Any tips are still appreciated!
Cheers,
Michael