I have an MKMapView with an iAd banner on top. Due to this iAd Banner covering the MKMapView's legal label, it is moved. The following code is performed in viewDidLayoutSubviews:
NSLog(#"ViewDidLayoutSubviews called");
UILabel *attributionLabel = [self.mapView.subviews objectAtIndex:1];
if (adBannerViewFrame.origin.y < attributionLabel.frame.origin.y) {
NSLog(#"Banner Y coordinate: %f", adBannerViewFrame.origin.y);
CGRect legalFrame = attributionLabel.frame;
legalFrame.origin.y -= IAD_BANNER_HEIGHT;
attributionLabel.frame = legalFrame;
NSLog(#"Legal y: %f", legalFrame.origin.y);
NSLog(#"Legal x: %f", legalFrame.origin.x);
NSLog(#"Legal width: %f", legalFrame.size.width);
NSLog(#"Legal height: %f", legalFrame.size.height);
}
When I switch from the View Controller containing the map to another VC and back again, the code above works perfect, regardless of orientation; however, when rotating the devices without switching VCs, the legal label disappears on rotation and don't come back until I switch back and fourth between VCs again. The NSLogs print out the exact same for both rotation and VC switching:
ViewDidLayoutSubviews called
Banner Y coordinate: 902/646(rotation dependent)
Legal x: 882/626(rotation dependent)
Legal y: 11
Legal width: 48
Legal height 11
Despite everything looking the same, the label is gone after rotating (not sure if it is moved out of the view or if it actually disappears)
The iAd Banner is reloaded in ViewDidAppear (which is called when VCs are switched back and fourth). However, since the NSLogs print the same for both scenarios, I cannot see how it should make any difference. To be sure, I tried to reload the iAd Banner in ViewDidLayoutSubviews as well, with no different result than before. Anyone experienced anything similar or know how to fix this?
For anyone encountering the same issue, I found a solution. The workaround was to schedule a timer with 0 seconds and have the timer call the method executing the code above.
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(test) userInfo:nil repeats:NO];
I assume that something was not completely finished when viewDIDlayoutSubviews was called and that adding a timer (which is not 100 % accurate and will therefore not start immediately), allowed the unknown remaining stuff to complete before the code in the question was executed.
Related
I am trying to get my rock.png to move to the side(+x axis) when my mouse is moving. You can see that _target is the position of the event and the event is the mouse moving.
I then got the node image and set it to a variable.
In the else statement I made the rock.position the position of the _target and gave it somee space away from the _target
I want this to move because my camera moves and I want it to move with the flow of the camera
``
extends Camera2D
const zone = 10
onready var rock = get_node("rocks_png_1")
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
var _target = event.position
if _target.length() < zone:
self.position = Vector2(640,350)
else:
self.position = _target.normalized() * (_target.length() - zone) * 0.5
rock.position = Vector2(int(_target)+40, int(_target)+20)
``
From the code I used above I get this error
Invalid get Index 'position' (on base: 'TextureRact')
I tried just using the same code as I used in my self.position for the camera that made it move, but when I try it for the rock.position it gives me an error that tells me I need a Vector?
Invalid get Index 'position' (on base: 'TextureRact')
The error is telling you that TextureRect does not have a position property.
What happens is that a TextureRect is a Control which are positioned differently from Node2D (Camera2D is a Node2D). You can try using rect_position with it. Although I think you would be better off using a Sprite instead of a TextureRect (Sprite is a Node2D).
Notice that your TextureRect is a child of the Camera2D in the scene tree. Well, a Node2D would move with its parent automatically. So changing it to Sprite would negate the need of the line of code you are using to move it.
… Actually, due to the way Camera2D works (it has drag and limits) you might still want do something (depending what your goal is). So, know that the get_camera_screen_center method will give you the actual visual center of the screen (which is not the target of the Camera2D, again due to drag and limits).
I can't seem to get a QGraphicsEllipseItem to show up in my view. I am attempting to use it in combination with a QGraphicsLineItem:
# Instantiate the line object:
self.profileLine = QGraphicsLineItem()
self.profileLine.setPen(QPen(Qt.yellow, 1.0))
self.profileLine.setLine(self.StartX, self.StartY, self.StopX, self.StopY)
self.scene.addItem(self.profileLine)
# Instantiate the circle:
self.profileStopHandle = QGraphicsEllipseItem()
self.profileStopHandle.setPen(QPen(Qt.yellow, 1.0))
self.profileStopHandle.setRect(self.StopX, self.StopY, 50, 50)
self.scene.addItem(self.profileStopHandle)
Later, in my mouse move event, I determine the current mouse coordinates, assign them to StopX/StopY and redraw the line from the start point to the new stop point as well as draw the ellipse around the new stop point:
self.profileLine.setLine(self.StartX, self.StartY, self.StopX, self.StopY)
self.profileStopHandle.setPos(self.StopX, self.StopY)
The line shows up fine and behaves just as it should, but no matter what I cannot seem to get the ellipse to draw. I know the point coordinates I'm passing to it are correct because they are the same ones I'm using for the line. The ellipse just never appears as if it was never created in the first place. What am I doing wrong here (it must be something very basic)? Thank you in advance.
The issue was the Z-value (amateur mistake). I brought the ellipse to the foreground and now it is visible:
self.profileStopHandle.setZValue(self.sceneImage.zValue() + 1.0)
I've 3 (loader, locker and debug view) hidden views (touchEnabled and visible set to false, and zIndex to 1) above the main view (zIndex = 2).
Each 'over' view has this method:
$.debugView.show = function() {
$.debugView.touchEnabled = $.debugView.visible = true;
$.debugView.zIndex = 3;
};
$.debugView.hide = function() {
$.debugView.touchEnabled = $.debugView.visible = false;
$.debugView.zIndex = 1;
};
This screen has the 3 'over' views hidden:
Now, I'm opening the 'debug view', but, SOMETIMES it seems like it changes the positions (as if the center it's on the top left corner instead of the center of the device).
Instead of the required result:
If I use the opacity instead of the visible property, it works properly.
This might be an SDK bug right?
<Alloy>
<Window>
<View id="content"/>
<View id="locker"/>
<View id="loader"/>
<View id="debugView"/>
</Window>
</Alloy>
All of these 4 views don't have width or height (so it uses the Ti.UI.FILL as default)
I have noticed this too with a completely different implementation. I had just one view that I included in a window.
Apparently the left and top calculations were not done properly if the elements is hidden.
What I did to solve the issue is to hardcode the left/top position by calculating the left position using this:
$.content.left = (Ti.Platform.displayCaps.platformWidth - 75) / 2;
Where in my case 75 is the width the element has, so that'll be bigger in your case. You can do the same for height.
Now, this is an iOS only solution. On Android you will need to take DPI into consideration calculating it.
I do think it is a bug, though this solution works perfectly for me. I recommend looking at JIRA and see if it is a known issue, and if not, raise it with a very specific explanation of the problem, preferably with a reproducible case delivered as an app. Classic would help most. And if it is not reproducible in classic it might be an alloy issue.
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;
I'm a little new to using MFC and VC++ as such, but I'm doing this as part of a Course and i Have to stick to VC++.
http://www.cprogramming.com/tutorial/game_programming/same_game_part1.html
This is the tutorial I have been following to make a simple samegame. However when i try to display score, the score is getting displayed Underneath or outside my application window, even though I've displayed score before calling updateWindow(). I've tried various methods but I am kinda lost here.
Here is the code I'm using to Display the score:
void CSameGameView::updateScore()
{
CSameGameDoc* pDoc = GetDocument();
CRect rcClient, rcWindow;
GetClientRect(&rcClient);
GetParentFrame()->GetWindowRect(&rcWindow);
int nHeightDiff = rcWindow.Height() - rcClient.Height();
rcScore.top=rcWindow.top + pDoc->GetHeight() * pDoc->GetRows() + nHeightDiff;
rcScore.left=rcWindow.left + 50;
rcScore.right=rcWindow.left + pDoc->GetWidth() - 50;
rcScore.bottom=rcScore.top + 20;
CString str;
double points = Score::getScore();
str.Format(_T("Score: %0.2f"), points);
HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
COLORREF clr = pDoc->GetBoardSpace(-1, -1); //this return background colour
pDC->FillSolidRect(&rcScore, clr);
DrawText(hDC, (LPCTSTR) str, -1, (LPRECT) &rcScore, DT_CENTER);
}
Thank you for any help and I'm sorry if the question doesn't make sense or in ambiguous.
There are several problems with your code:
1. The hDC you are creating is going to have coordinates relative to the desktop window. To paint text in your window, use CClientDC like this: CClientDC dc(this); (see http://msdn.microsoft.com/en-US/library/s8kx4w44%28v=vs.80%29.aspx)
2. The code you have will leak a DC every time the function is called. The method in #1 will fix that.
3. Your paint code should be done in the CView::OnDraw. There you get a DC passed to you and you don't have to worry about creating one with CClientDC. Set the variables you want to draw (e.g. your points or score), store them as class members and draw them in CView::OnDraw.
Don't do the drawing in your updateScore method.
Make sense? Hang in there!