Showing one cell at a time for UICollectionView - xamarin.ios

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

Related

Changing all Shape's colors at once JavaFX

I'm writing a small program in which multiple shapes will be visible in JavaFX. I'm trying to create a button through which it is possible to change all the shape's color to the chosen one by the user.
Right now, I'm only able to do that by changing each shape individually in my lambda expression. It's okay for now since there's only three shapes, but it will be inconvenient further one. Can anyone think of a way to group all the shapes together and access the "setFill" method to change them all at once?
Here's the code:
// Calling Semi-Circle method
Arc semicircle1 = shapes1.getsemicircle();
// create Colors button and set is as invisible until a shape value is passed by user
Button buttonColors = new Button();
buttonColors.setText("Choose a color for the Shape");
buttonColors.setVisible(true);
buttonColors.setOnAction( e ->
{
if (textField1.getText().equalsIgnoreCase("Grey"))
{
label1.setText("Grey");
semicircle1.setFill(Color.GREY);
}
});
You may create some property and bind all shapes to it
final ObjectProperty<Paint> fillProperty = new SimpleObjectProperty(Color.GREY);
...
semicirle1.fillProperty().bind(fillProperty);
pentagon1.fillProperty().bind(fillProperty);
rectangle1.fillProperty().bind(fillProperty);
...
fillProperty.set(Color.RED);

Any way to get a HaxeFlixel group to clear out?

There is a too long, didn't read version down below.
So I've been making a little game in which the player has to click on a grid of bricks that matches the color of the needed brick in the upper right hand corner of the screen. After they click on the needed color, the bricks explode and the bricks of the same color next to them explode as well creating combos. That leaves holes in the grid so I have to somehow reset the grid itself without resetting the gamestate itself. I've got something working right now which is this:
private function ResetNow():Void
{
if (Restter == 1) Restter = 0;
//if this block is up here, same results
/*
wantedBricks.kill();
wantedBrik._changeColor = FlxMath.rand(0, 2);
bricks.autoReviveMembers = true;
bricks.revive();
*/
Restter = 0;
//Removes stray detectors so the neverending combo bug won't occur
for (stray in dets.members) stray.kill();
if (Restter == 0)
{
wantedBricks.kill();
wantedBrik._changeColor = FlxMath.rand(0, 2);
bricks.autoReviveMembers = true;
bricks.revive();
wantedBricks.autoReviveMembers = true;
wantedBricks.revive();
for (zgem in bricks.members) zgem.EQUITYCHECK = FlxMath.rand(0, 2);
}
//add(bricks);
Restter = 1;
}
So, again, I have a grid of blocks set up at create, that is group bricks. And I have a sprite in the upper right corner which is wantedBrik. What happens during gameplay, is the player clicks on the bricks that matches the wanted bricks to clear them out of the grid. When there are no more wantedBricks(a group), it is supposed to reset the grid, and change the color of the wantedBrik. I also have it somewhere else in the code that if a member of the big grid's EQUITYCHECK(basic object hacked in value) is equal to the wantedBrik, add it to the wantedBricks(which, is why I'm checking for no more of them). So, what happens?
Well, if the color of the wantedBrik doesn't change, everything's fine and resets like normal. the wantedBricks group acurately counts the bricks that actually match the wantedBrik's color. And when it does change, for some reason, gameplay is normal. BUT, wantedBricks not only thinks that the old color is still needed, but it also thinks the new color is still needed too. So when the player clicks the new needed color bricks, they do explode, but because wantedBrik thinks the old color is still wanted, it doesn't hit null and the grid won't reset.
What can I do to make sure that wantedBricks behaves correctly after a color change?
TL;DR version: I need to get a Haxe array to forget or lose old numbers. How can I do this?
The "Pirate Pig" sample may be useful to you. Since it is a puzzle game, there may be some similar problems that were solved there. You can find it using openfl create or nme create depending on which you are currently using.
You can create a simple array like this:
var myArray = [];
You can also type arrays, like this:
var numbers = new Array<Float>();
Then you can use push(), concat() and other array methods.

Flot pie charts - externally selecting slices

I found this solution.
If type of chart is pie, how specify parameters (x,y) of highlight(x, y)?
Thanks
Sorry for my bad English.
Unfortunately, flot doesn't expose the pie highlighting code to the user. So we are pretty much out of luck, but what may work for you is synthesizing a click event at the appropriate place on the page:
$("#highligher").click(function () {
var e = jQuery.Event('click');
e.pageX = 250; //add a made up x/y coordinate to the click event
e.pageY = 250;
$('#plot canvas:first').trigger(e); //trigger the click event on the canvas
});
Here it is in action: http://jsfiddle.net/ryleyb/mHJm5/
The problem is you have to know where the slice you want to highlight is already. This would be easy enough to set if the graph is static. If it's a dynamic graph, you'd have to dig into the source of the pie code to figure out how to calculate where the pie slice is. It might be easier in that case to just have a copy of all the pie functions and manually draw on the pie overlay.
Just got this working by altering a few things...
I changed highlight and unhighlight in jquery.flot.pie.js to pieHighlight and pieUnhighlight.
Then, after these two lines in jquery.flot.pie.js...
plot.hooks.processOptions.push(function(plot, options) {
if (options.series.pie.show) {
I added...
plot.highlight = pieHighlight;
plot.unhighlight = pieUnhighlight;
We're maintaining selection state outside of the chart (as a backbone model). When a selection event (click) occurs, we set the selected slice in the model. When selection changes, we refresh the chart using a selection color for the pie slices that are selected.
var data = [];
var color = slice.index == selected ? '#FF0000' : '#0000FF';
data.push({label:slice.Label,data:slice.Value,color:color});
The snippet above uses blue for all non-selected slices, red for the selected slice. Your color logic will be more sophisticated.
NOTE: You can also use rgba CSS for the colors, which gives a really nice effect. For example:
var color = slice.index == selected ? 'rgba(0,0,255,1)' : 'rgba(0,0,255,0.5)';

Resize CATextLayer to fit text on iOS

All my research so far seems to indicate it is not possible to do this accurately. The only two options available to me at the outset were:
a) Using a Layout manager for the CATextLayer - not available on iOS as of 4.0
b) Use sizeWithFont:constrainedToSize:lineBreakMode: and adjust the frame of the CATextLayer according to the size returned here.
Option (b), being the simplest approach, should work. After all, it works perfectly with UILabels. But when I applied the same frame calculation to CATextLayer, the frame was always turning out to be a bit bigger than expected or needed.
As it turns out, the line-spacing in CATextLayers and UILabels (for the same font and size) is different. As a result, sizeWithFont (whose line-spacing calculations would match with that of UILabels) does not return the expected size for CATextLayers.
This is further proven by printing the same text using a UILabel, as against a CATextLayer and comparing the results. The text in the first line overlaps perfectly (it being the same font), but the line-spacing in CATextLayer is just a little shorter than in UILabel. (Sorry I can't upload a screenshot right now as the ones I already have contain confidential data, and I presently don't have the time to make a sample project to get clean screenshots. I'll upload them later for posterity, when I have the time)
This is a weird difference, but I thought it would be possible to adjust the spacing in the CATextLayer by specifying the appropriate attribute for the NSAttributedString I use there, but that does not seem to be the case. Looking into CFStringAttributes.h I can't find a single attribute that could be related to line-spacing.
Bottomline:
So it seems like it's not possible to use CATextLayer on iOS in a scenario where the layer is required to fit to its text. Am I right on this or am I missing something?
P.S:
The reason I wanted to use CATextLayer and NSAttributedString's is because the string to be displayed is to be colored differently at different points. I guess I'd just have to go back to drawing the strings by hand as always....of course there's always the option of hacking the results from sizeWithFont to get the proper line-height.
Abusing the 'code' tags a little to make the post more readable.
I'm not able to tag the post with 'CATextLayer' - surprisingly no such tags exist at the moment. If someone with enough reputation bumps into this post, please tag it accordingly.
Try this:
- (CGFloat)boundingHeightForWidth:(CGFloat)inWidth withAttributedString:(NSAttributedString *)attributedString {
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString( (CFMutableAttributedStringRef) attributedString);
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(inWidth, CGFLOAT_MAX), NULL);
CFRelease(framesetter);
return suggestedSize.height;
}
You'll have to convert your NSString to NSAttributedString. In-case of CATextLayer, you can use following CATextLayer subclass method:
- (NSAttributedString *)attributedString {
// If string is an attributed string
if ([self.string isKindOfClass:[NSAttributedString class]]) {
return self.string;
}
// Collect required parameters, and construct an attributed string
NSString *string = self.string;
CGColorRef color = self.foregroundColor;
CTFontRef theFont = self.font;
CTTextAlignment alignment;
if ([self.alignmentMode isEqualToString:kCAAlignmentLeft]) {
alignment = kCTLeftTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentRight]) {
alignment = kCTRightTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentCenter]) {
alignment = kCTCenterTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentJustified]) {
alignment = kCTJustifiedTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentNatural]) {
alignment = kCTNaturalTextAlignment;
}
// Process the information to get an attributed string
CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
if (string != nil)
CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)string);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTForegroundColorAttributeName, color);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTFontAttributeName, theFont);
CTParagraphStyleSetting settings[] = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTParagraphStyleAttributeName, paragraphStyle);
CFRelease(paragraphStyle);
NSMutableAttributedString *ret = (NSMutableAttributedString *)attrString;
return [ret autorelease];
}
HTH.
I have a much easier solution, that may or may not work for you.
If you aren't doing anything special with the CATextLayer that you can't do a UILabel, instead make a CALayer and add the layer of the UILabel to the CALayer
UILabel*label = [[UILabel alloc]init];
//Do Stuff to label
CALayer *layer = [CALayer layer];
//Set Size/Position
[layer addSublayer:label.layer];
//Do more stuff to layer
With LabelKit you don't need CATextLayer anymore. No more wrong line spacing and wider characters, all is drawn in the same way as UILabel does, while still animated.
This page gave me enough to create a simple centered horizontally CATextLayer : http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html
- (void)drawInContext:(CGContextRef)ctx {
CGFloat height, fontSize;
height = self.bounds.size.height;
fontSize = self.fontSize;
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0.0, (fontSize-height)/2.0 * -1.0);
[super drawInContext:ctx];
CGContextRestoreGState(ctx);
}

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