Blur TableView except one Cell - xcode

How can you blur the whole view except a single table view cell?
The effect should be similar to the 3D touch blur effect. E.g. Mail app:

The effect of blur applies precisely to the whole screen but the selected cell in the case of the mail app.
If you only want the effect to apply to your table view, you could maybe put a blur visual view on tope of your each cell's content, and set its effect to nil
cell.blurView.effect = nil
appart when one cell is selected. To do that, play with the didSelectRow function and reload the data so that at the end you get the effect you want. (you can even animate the change with UIView.animate())
UIView.animate(withDuration: 0.5, animations: {
cell.blurView.effect = UIBlurEffect.init(style: .light)
}
The problem is that the solution I told you is not very power efficient, but I can think of another one:
Consider having two blur view that display no effect when no cell is selected, then you can as soon as the cell is selected, set the two blur view so that the first one takes the whole part of the screen at the TOP of your cell, and the other one covers the BOTTOM.
Ok last idea:
you could, in the didSelectRow method, add a blurView to the whole screen
UIApplication.shared.keyWindow?.addSubview(blurView)
and then add the cell on top of that and of course removing all this when the blur view is tapped for example
Hope it helps ;)

Related

Superview not resizing with subviews

I have a window into which I horizontally add two subviews. Into each subview, I place a variable number of subviews made up of a vertical slider, a text field rotated 90 degrees and placed to the left of the slider and another textfield, placed just under the slider. The slider subview's constraints are done in code, the parent views are both done in IB. When I add more slider views to the left window than the subview can handle in its default size, it resizes horizontally and forces the window's content view (and window) to also resize horizontally. Great, that's just what I want. But if I add more slider subviews than can fit in the right subview, they just get squeezed together and the subview does not expand as the left. I layout the slider views using code with this category converted to support NSViews, instead of UIVews:
UIView+AutoLayout1: https://github.com/jrturton/UIView-Autolayout
The constraints for the left and right subviews are more or less the same. I can't figure out why the right view does not resize as the left view does.
Here is a link to a sample project that demonstrates the problem:
SliderTest
Some someone help me out with this?
Also, a secondary question as I think my slider view could use a little work:
When a view is rotated using setFrame(Center)Rotation, do the top, right, bottom and top edges remain along the same edges or do they reflect the new orientation of the rotated view?
Thanks
I found the problem. The constraint between the left view and right edge of the window was fixed at 233 instead of >= 233. I had this at some point in the past, as I was adjusting the constraints to achieve the desired behavior and just overlooked this one through the troubleshooting process.

How can I blend in my SegmentedControl in a UITableView better?

As you can see on the screenshot the segmented control is placed rather ugly this way.
I need it in that place, meaning below the section title and before the second cell for that section. How could I make this better?
I can think of two suggestions that would improve the appearance. The first would be to increase the height of the table cell (just that particular table cell, not all of the cells in your table) so that the whitespace margin at the top and bottom of your segmented control is equal to the margin you currently have on the left and right of the control.
Another solution would be to move the selection of the value for this setting into a separate tableView controller that you drill down to. So that cell would show the current value, but tapping the cell would take the user to a new view where the user could select to change the value.
Here is an example of this from the Instapaper app settings page that I think looks pretty clean.

Resize animations on a scrollview

I am trying to create a resize toggle animation on this simple custom TUIScrollView class (from TwUI open source project and very similar to UIScrollView) that I have built. It is called TUILayout and supports horizontal layout as well as vertical, animated insertions and removals and has a more declarative way of supplying data to it's cells that I prefer over delegation. It recycles views similar to TUITableView or UITableView. Anyway if you want to follow along, it's just one class and is here.
https://github.com/mrjjwright/TUILayout.
In the example code, the user clicks the blue button in the lower left and all the rows shrink smoothly to a size where the user can reorder and delete some rows (right click on a row in the example to see this in action), etc... and then the user toggle the rows back out to their original size by clicking the blue button again.
While doing this resize in setObjectHeight:animated I first resize my model objects that represent the rows, recalculate and set the contentSize on the TUIScrollView, cycle in all the new views (say 10 more views will fit in the shrunk view so dequeueReusableView and addSubview gets called 10 times) and finally I animate the frames of all the views to their size and location in layoutSubviews.
The result is that the scrollview correctly shrinks to a size where the scrollbar no longer displays, the views that are on screen animate smoothly down to their reduced size, but the newly added subviews that can now fit in the visibleRect animate in much later as one block of subviews.
So all the newly added subviews lag behind the views that were on the screen and I can't figure out why the animation isn't all happening together. I have tried lots of different combos of things with no luck including CATransactions. I am wondering if it has to with how a CAScrollLayer works or if somebody can help me think through this.
The more general issue is how to smoothly handle resizing animations on scrollviews that recycles their views and I have looked at several other grids out there in the iOS world and have got some inspiration but am looking for more.
Thanks!
I think I might have solved my own issue here (as I was making my bed this morning it hit me). I forced the current runloop to run after cycling in all the necessary subviews and very importantly not setting the contentSize of the scrollview until after the run loop completes and adds the needed subviews for the animation. In order to get the run loop to fire I used the trick from this SO question:
skipLayout = YES;
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
skipLayout = NO;
If skipLayout is set TUILayout just returns from layoutSubviews so that the views just added are not immediately removed by the recycling layout code. Forcing the run loop to run made sure that all subviews were on the screen for the animation. After this I performed the resize animated layout. I updated the code on github if anybody is interested. I will leave this question open for a while to gain some further insight.

NSOutlineView badges in NSSplitView

I have an NSOutlineView which I draw badge numbers to the right side of cells using drawAtPoint:, NSAttributedString, and of course NSBezierPath. My problem exists when resizing of the outline view occurs when within a subview of an NSSplitView. The badges move along with the resize to the left or right. When they get to the text of the cells themselves they do not stop or truncate the text under them. It just flies right over.
Is there a way to have the cell recognize the custom drawn view next to it and truncate text accordingly? I have tried the solution PXSourceList already, but that did not help either.
"PXSourceList solution" working good. You subclass NSOutlineView and overload frameOfCellAtColumn for this particular task. At this function you need to decrease width of cellFrame, returned from super call, by the width of your badge plus padding.

What is the best way to make a QTableView's cells have up and down button pushed states in Qt?

I'm trying to make the cells of a QTableView look like 3D clickable buttons. So that when you click on a cell, the button looks pushed. Everyone seems to think I merely want to change the colour, I need to show images of a normal button, and a pushed button, that look 3-dimensional.
I have done this already with calling QTableView::setItemDelegate(), with an appropriate ItemDelegate that will change the background of the cell when it's clicked. However I'm stuck at this point because I want some cells to be different coloured buttons based on the data they contain. So a cell with a low number would be a red button, that's also red when it's clicked, and the other cells would be different colours.
I can set the colour of the button with the TableModel, but once the button is clicked, there is no way for the ItemDelegate to know that it's supposed to be a different colour than the rest. How can you link the two so the ItemDelegate knows what colour it's supposed to be?
Also, is there simply a better way to make cells look like buttons?
You can call QModelIndex::model() from within the ItemDelegate's paint() method, since it has a QModelIndex parameter. This gives you the TableModel for the data, which you can programatically decide what colour the cell's button will be.
However, this is still not as elegant as I'd hope. Does anyone know a better way to change the appearance of table cells when in both the up and down button push states?
Why don't you asked the index for the background color.
Something like this ...
QStyleOptionToolButton buttonOption;
const QStyleOptionViewItemV4& optionV4 = dynamic_cast<QStyleOptionViewItemV4&>(option);
//...
buttonOption.palette.setBrush( QPalette::Button, index.data( Qt::BackgroundColorRole ) );
//...
I have feeling that its a bug in Qt and its must have been ...
// model code
if(role==Qt::BackgroundColorRole )
return qvariant_cast<QBrush>( QBrush(Qt::red) );
// delegate code
buttonOption.palette.setBrush(QPalette::Button, optionV4.backgroundBrush );
Because the optionV4.backgroundBrush is correct in the sizeHint method but is invalid in the paint method . I see now reason why the sizeHint should have the background brush and the paint method not. I'll report it to Nokia.
EDIT:
Looks like I was right and its a bug in < Qt4.5.
QStyleOptionViewItemV4 doesn't copy the icon and backgroundBrush
Can you not get the ID/row count of the table cell's row and then check it against the colour table that you may be having, and set the colour accordingly? I am not sure if I understood your question well or not.
Assign a data role for the background color, and in your item delegate, ask the model index what it's background color is (using data( bg_color_role ) or something similar). Then, in your model, you need to make sure the data function returns a color for the bg_color_role that is appropriate for the data being modeled.
The way to do that is to use the data method of the QModelIndex object you get on the paint method, and ask for a specific role (if you define a custom model, you can add your own roles, and give the information you need to the delegate in those roles.)
TimW, I think you have to fill the QStyleOptionViewItemV4 info by calling initStyleOption before.
I'm not sure where the requirement for a background image comes from. If you want the cells to look like QPushButtons, you should probably inherit from QItemDelegate and implement paint() to use QStyle to draw you a QPushButton, something like this:
QStyleOptionButton opt;
// fill 'opt' from the information from the model, and the style option that's passed in
style()->drawControl( QStyle::CE_PushButton, &opt, painter );
Have you tried using custom style sheets?
You could just apply the same stylesheet to every cell, and then change the background image / style to draw the 3D button images depending on whether or not it's selected.

Resources