UIDragItem causes memory leak when Context Menu has been initialised - memory-leaks

I have a CollectionView with Drag and Drop and Context Menu functionality. There's a memory leak caused by returned [UIDragItem] array in ItemsForBeginning method when I initialise cell's context menu.
Objects are being kept in memory when I pop to rootViewController. All is OK though when drag session is being happened.
I've ended up commenting out everything, keeping blank UIDragItem and problem is still there:
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let dragItem = UIDragItem(itemProvider: NSItemProvider(object: "" as NSString))
return [dragItem]
}
Does anybody experience this?
Looks like it's a UIKit bug...
Please help!

Related

Showing one cell at a time for UICollectionView

I have a collectionview I want to show just one cell at a time and based on my findings on SO it should be as simple as setting the item size to the size the collectionview itself but when I did that I see still a small bit of the next cell.
Here is how I've set up my collectionview:
cvCarousel.RegisterNibForCell(CarouselItemCollectionViewCell.Nib, CarouselItemCollectionViewCell.Key);
cvCarousel.CollectionViewLayout = new UICollectionViewFlowLayout
{
ItemSize = new CGSize(cvCarousel.Frame.Width, cvCarousel.Frame.Height),
MinimumInteritemSpacing = 0,
MinimumLineSpacing = 0,
ScrollDirection = UICollectionViewScrollDirection.Horizontal
};
I'm sure there's something simple I'm missing here but not sure what it is.
I guess you're calling the following code in viewDidLoad method.
Everything will have whatever frame size and position after a while until the layout has been performed, however it is too early in viewDidLoad method , we can only get the correct frame in viewDidLayoutSubviews method.
However , here you can directly replace cvCarousel.Frame with UIScreen.MainScreen.Bounds , because you just need a full screen item.
Refer to
https://developer.apple.com/forums/thread/52578

F# Winforms Charting Asynchronous Updating

I'm trying to create a chart in winforms that databinds to a list in memory, and gets updated dynamically as the list changes. Here is my code:
open System
open System.Linq
open System.Collections
open System.Collections.Generic
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.DataVisualization
open System.Windows.Forms.DataVisualization.Charting
let link = new LinkedList<double>()
let rnd = new System.Random()
for i in 1 .. 10 do link.AddFirst(rnd.NextDouble()) |> ignore
let series = new Series()
let chart = new System.Windows.Forms.DataVisualization.Charting.Chart(Dock = DockStyle.Fill, Palette = ChartColorPalette.Pastel)
series.Points.DataBindY(link)
let form = new Form(Visible = true, Width = 700, Height = 500)
form.Controls.Add(chart)
let formloop = async {
while not chart.IsDisposed do
link.AddFirst((new System.Random()).NextDouble()) |> ignore
link.RemoveLast()
}
do
Async.StartImmediate(formloop)
Application.Run(form)
Console.WriteLine("Done")
Console.ReadLine() |> ignore
The async seems to work, but the chart never shows anything. It just shows a blank window. What am I doing wrong?
LinkedList<T> has no way to signal that it's been updated, so Chart has no way of knowing when to redraw itself.
In order for databinding to update the view, the source list must implement IBindingList and raise appropriate event when the contents change.
Separately, I must point out that it's dangerous to directly access UI properties/methods from non-UI threads (such as chart.IsDisposed in your code). In WinForms, this limitation is rarely actually enforced, so sometimes this might seem to work fine, only to crash later on a customer's machine with no way to attach a debugger.
You need to add the series to the SeriesCollection of the chart.
chart.Series.Add series
You need to construct a chart area and add it to the ChartAreaCollection of the chart.
let area = new ChartArea()
chart.ChartAreas.Add area
You need to make sure that the data binding method is called after the chart and form are set up.
...
form.Controls.Add chart
series.Points.DataBindY link
And now there's no way to communicate changes of your bound collection to the DataPointCollection of the series, as mentioned in Fyodor Soikin's answer. I'm not quite sure that IBindingList is an appropriate response;
while it's possible to hook into the ListChanged event, we could as well manipulate the series' DataPointCollection directly.
let formloop = async{
while not chart.IsDisposed do
series.Points.RemoveAt 0
series.Points.AddY(rnd.NextDouble()) |> ignore
do! Async.Sleep 100 }
Finally I'd like to point out this contribution by John Atwood which adresses both points raised by Fyodor; the data binding issue (by not using it) and the UI-thread safety issue.

NSSplitViewItem collapse animation and window setFrame conflicting

I am trying to make a (new in 10.10) NSSplitViewItem collapse and uncollapse whilst moving its containing window so as to keep the whole thing "in place".
The problem is that I am getting a twitch in the animation (as seen here).
The code where I'm doing the collapsing is this:
func togglePanel(panelID: Int) {
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
// Toggle the collapsed state
NSAnimationContext.runAnimationGroup({ context in
// special case for the left panel
if panelID == 0 {
var windowFrame = self.view.window.frame
let panelWidth = splitViewItem.viewController.view.frame.width
if splitViewItem.collapsed {
windowFrame.origin.x -= panelWidth
windowFrame.size.width += panelWidth
} else {
windowFrame.origin.x += panelWidth
windowFrame.size.width -= panelWidth
}
self.view.window.animator().setFrame(windowFrame, display: true)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}, completionHandler: nil)
}
}
I am aware of the "Don't cross the streams" issue (from session 213, WWDC'13) where a window resizing animation running on the main thread and a core animation collapse animation running on a separate thread interfere with each other. Putting the splitViewItem collapse animation onto the main thread seems like the wrong approach and I've got a nagging feeling there's a much better way of doing this that I'm missing.
Since I am not finding any documentation on the NSSplitViewItems anywhere (yet) I would appreciate any insights on this.
I have the little test project on GitHub here if anyone wants a look.
Update The project mentioned has now been updated with the solution.
Thanks,
Teo
The problem is similar to the "don't cross the streams" issue in that there are two drivers to the animation you've created: (1) the split view item (2) the window, and they're not in sync.
In the example from the '13 Cocoa Animations talk, constraints were setup to result in the correct within-window animation as only the window's frame was animated.
Something similar could be tried here -- only animating the window's frame and not the split view item, but since the item manages the constraints used to (un)collapse, the app can't control exactly how within-window content animates:
Instead the split view item animation could completely drive the animation and use NSWindow's -anchorAttributeForOrientation: to describe how the window's frame is affected.
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
let window = self.view.window
if panelID == 0 {
// The Trailing edge of the window is "anchored", alternatively it could be the Right edge
window.setAnchorAttribute(.Trailing, forOrientation:.Horizontal)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}
For anyone using Objective C and targeting 10.11 El Capitan.
This did the trick for me, didn't need to set AnchorAttributes.
splitViewItem.collapsed = YES;

QGraphicsView not showing the picture

I have a "tooltip.png" file in my local directory.
the code below works when i put it in int main() but doesn't work when i put it in my MainWindow class constructor:
QGraphicsScene scene;
QGraphicsView *view = new QGraphicsView(&scene);
QGraphicsPixmapItem item(QPixmap("tooltip.png"));
scene.addItem(&item);
view.show();
in int main() it show the picture but in constructor doesn't
You create scene on the stack, meaning that it will be deleted once it goes out of scope, which is at the end of the constructor.
Try constructing scene like this inside the constructor of your MainWindow:
QGraphicsScene scene(this);
By providing a parent to the scene, Qt will make sure it remains alive together with that parent (in your case you mainWindow).
Since Qt takes care of the memory management, you can use pointers without fear of memory leaks:
QGraphicsScene* scene = new QGraphicsScene(this);
QGraphicsView* view = new QGraphicsView(scene, this); // Give the view a parent too to avoid memory leaks
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap("tooltip.png"), this);
scene->addItem(&item);
view->show();

How to avoid CListCtrl items to be partially visible?

I have a resizeable CListCtrl and I want to avoid any item being displayed partially, ever.
For example:
I want Item 9 to not be displayed in this case. Is there a flag or method for this? How would you go about solving this issue?
I tried the following and it was no good:
void CMyCListCtrl::OnEndScrolling()
{
int iCount = this->GetCountPerPage();
EnsureVisible(iCount - 1, FALSE);
}
after catching
...
ON_NOTIFY( LVN_ENDSCROLL, IDC_LIST1, OnEndScroll )
...
void CWheelTestDlg::OnEndScroll(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVSCROLL pnmLVScroll = (LPNMLVSCROLL) pNMHDR;
m_MyListCtrl.OnEndScrolling();
*pResult = 0;
}
In the CListCtrl parent dialog. (which I don't want to do, I want to do everything in my CListCtrl derived class only, if possible).
All I accomplish is showing item 9 completely, but item 10 is partially visible below it. If I have 30 items I don't want to scroll the list to show item 30, I want to show up to item 8 with no partially visible item below it.
CListCtrl doesn't appear to support Integral Height.
Here's a solution that accomplishes what you desire by forcefully changing the control height [with commented conditions] (http://www.codeproject.com/Messages/418084/Socket-accept-call.aspx):
/////////////////////////////////////////////////////////////////////////////////
// This assumes a REPORT-style CListCtrl.
//
// Resize the control. This works correctly only if scrolling is disabled. If
// there is scrolling, then setting to the size from ApproximateViewRect() will
// always give scroll bars showing. Which is irritating.
//
// We need to adjust the vertical size from what ApproximateViewRect() returns
// by one row minus border width
//////////////////////////////////////////////////////////////////////////////////
CSize sz = m_list.ApproximateViewRect(); // always adds room for a new row
CRect itRect; // Get the height of a single row (there had better *be* a row!)
m_list.GetItemRect(0, &itRect, LVIR_BOUNDS);
int vOffset = itRect.Height() - 3; // leave a little 'cuz it looks better
m_list.SetWindowPos(NULL, 0, 0, sz.cx, sz.cy - vOffset,
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);
I have the similar problem in wince, and find a solution accidentally. No direct solution in internet, so i decide to re-position scroll bar after receive some message, and the only message i can used in wince is WM_LBUTTONDOWN, other messages such as OnEndScroll are not called, maybe something wrong in my code.
Whatever, i use Timer(ON_WM_TIMER) to re-position scroll bar when receive WM_LBUTTONDOWN message, then find that list control doesn't scroll automatically! then i remain a empty OnTimer function and remove everything else. It works, and i guess list control use Timer to scroll partial row.
Hope useful to you.

Resources