I want to set collectionview height with maxY of last collectionviewcell! But why SE simulator doesn't work? - collectionview

I want to set collectionview height with last item's maxY (not scrollable collectionview / grid collectionview / fixed width&height).
I get last index of item and get last item's layout using collectionView.layoutAttributesForItem(at: lastIndex)
and get maxY of the item and set collectionviewHeight to maxY.
But only SE simluator can't find correct maxY of last item?!
I don't know why SE simluator can't find correct maxY of last collectionview cell...
Here is my code (full code at github):
class CheckListTableViewCell: UITableViewCell {
var book = Book()
#IBOutlet weak var bookNameLabel: UILabel!
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var collectionViewHeight: NSLayoutConstraint!
var estimateWidth = 30.0
var cellMarginSize = 3.0
override func awakeFromNib() {
super.awakeFromNib()
setCollectionView()
}
func setCollectionView(){
collectionView.register(UINib(nibName: "PageCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PageCollectionViewCell")
self.translatesAutoresizingMaskIntoConstraints = false
if let flow = collectionView.collectionViewLayout as? UICollectionViewFlowLayout{
flow.minimumInteritemSpacing = CGFloat(self.cellMarginSize)
flow.minimumLineSpacing = CGFloat(self.cellMarginSize)
}
}
class func instanceFromNib( _ book:Book)->CheckListTableViewCell{
let cell = UINib(nibName: "CheckListTableViewCell", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CheckListTableViewCell
cell.book = book
cell.bookNameLabel.text = book.title
cell.collectionView.reloadData()
cell.setCollectionViewHeight()
cell.selectionStyle = UITableViewCell.SelectionStyle.none
return cell
}
}
extension CheckListTableViewCell:UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return book.pageList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PageCollectionViewCell", for: indexPath) as? PageCollectionViewCell else{
return UICollectionViewCell()
}
let page = book.pageList[indexPath.row]
cell.pageNumberLabel.text = page.pageNumber
return cell
}
}
extension CheckListTableViewCell:UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = self.calculateWith()
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let page = book.pageList[indexPath.row]
RealmManager.shared.changeIsReadOfPage(title: book.title, pageNumber: page.pageNumber, isRead: !page.isRead)
if let cell = collectionView.cellForItem(at: indexPath) as? PageCollectionViewCell{
cell.toggle(isRead:!page.isRead)
}
}
}
extension CheckListTableViewCell{
func calculateWith() -> CGFloat {
let estimatedWidth = CGFloat(estimateWidth)
let cellCount = floor(CGFloat(collectionView.frame.size.width / estimatedWidth))
let margin = CGFloat(cellMarginSize * 2)
let width = (collectionView.frame.size.width - CGFloat(cellMarginSize) * (cellCount - 1) - margin) / cellCount
return width
}
// it is very clean & simple to set collectionview height with maxY of last collectionview cell
// But only SE Simulator maxY is not correct why????!
func setCollectionViewHeight(){
let lastIndex = IndexPath(item: book.pageList.count-1, section: 0)
if let att = collectionView.layoutAttributesForItem(at: lastIndex){
collectionViewHeight.constant = att.frame.maxY
}
}
}

Related

Custom Toolbar in UINavigation Controller

I am having trouble understanding what approach to take to customize my own Toolbar in Xamarin.ios. The Navigation controller comes with its own default toolbar but how can i change the height and have my own buttons, background image.
What is the best approach for the above ?
You can create a custom navigationBar as you want .
public class xxxViewController: UIViewController
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NavigationController.NavigationBar.Hidden = true;
double height = IsiphoneX();
UIView backView = new UIView()
{
BackgroundColor = UIColor.White,
Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height),
};
UIButton backBtn = new UIButton() {
Frame = new CGRect(20, height-44, 40, 44),
Font = UIFont.SystemFontOfSize(18),
} ;
backBtn.SetTitle("Back", UIControlState.Normal);
backBtn.SetTitleColor(UIColor.Blue, UIControlState.Normal);
backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside);
UILabel titleLabel = new UILabel() {
Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height),
Font = UIFont.SystemFontOfSize(20),
Text = "xxx",
TextColor = UIColor.Black,
Lines = 0,
};
UILabel line = new UILabel() {
Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
BackgroundColor = UIColor.Black,
};
backView.AddSubview(backBtn);
backView.AddSubview(titleLabel);
backView.AddSubview(line);
View.AddSubview(backView);
}
double IsiphoneX()
{
double height = 44;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 64;
}
}
return height;
}
[Export("GoBack")]
void GoBack()
{
NavigationController.PopViewController(true);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NavigationController.NavigationBar.Hidden = false;
}
}
You can set the property of title , backButton and navigationBar as you need (such as text , color ,BackgroundColor ,font e.g.)

Cell Data not showing properly in table view swif4

I am using table view inside table view I have used some views and then I used cell but when i running in simulator its content not showing properly
I added screenshot please check it.
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return tc_array.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
print(b_description.bounds.size.height)
return 200 + b_description.bounds.size.height
// return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell : TermCell = tableView.dequeueReusableCell(withIdentifier: "TermCell", for : indexPath as IndexPath) as! TermCell
cell.tc_lebel.text! = tc_array[indexPath.row]
print(cell.tc_lebel.text!)
return cell
}
new image click on it
2: https://i.stack.imgur.com/Lwd8o.png . check it new image
[1]: https://i.stack.imgur.com/I9rYO.png constraint image
If you have placed your constraints correctly, I would suggest removing
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
print(b_description.bounds.size.height)
return 200 + b_description.bounds.size.height
}
And when you setup your view, in viewDidLoad you should add this for automatic row dimension
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = yourAverageCellRowHeight

MapKit not showing custom Annotation pin image on iOS9

My code worked fine from iOS 7 to 8. With the update yesterday the custom images on my pins were replaced by the standard pin image.
Any suggestions?
My code:
extension ViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView! {
if annotation is MKUserLocation {
return nil
}
let reuseId = String(stringInterpolationSegment: annotation.coordinate.longitude)
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.image = getRightImage(annotation.title!!)
}
let button = UIButton(type: UIButtonType.DetailDisclosure)
pinView?.rightCalloutAccessoryView = button
return pinView
}
}
The function to get the image returns a UIImage based on the name:
func getRightImage (shopName:String)-> UIImage{
var correctImage = UIImage()
switch shopName
{
case "Kaisers":
correctImage = UIImage(named: "Kaisers.jpg")!
default:
correctImage = UIImage(named: "sopiconsmall.png")!
}
return correctImage
}
No the map looks like this:
Instead of creating an MKPinAnnotationView, create a plain MKAnnotationView.
The MKPinAnnotationView subclass tends to ignore the image property since it's designed to show the standard red, green, purple pins only (via the pinColor property).
When you switch to MKAnnotationView, you'll have to comment out the animatesDrop line as well since that property is specific to MKPinAnnotationView.
Following code works perfectly on all iOS 6 to iOS 9 devices:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// create a proper annotation view, be lazy and don't use the reuse identifier
MKAnnotationView *view = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"identifier"];
// create a disclosure button for map kit
UIButton *disclosure = [UIButton buttonWithType:UIButtonTypeContactAdd];
[disclosure addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(disclosureTapped)]];
view.rightCalloutAccessoryView = disclosure;
view.enabled = YES;
view.image = [UIImage imageNamed:#"map_pin"];
return view;
}
For Swift 4
func mapView(mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = String(stringInterpolationSegment: annotation.coordinate.longitude)
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinView == nil {
pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.image = getRightImage(annotation.title!!)
}
let button = UIButton(type: UIButtonType.DetailDisclosure)
pinView?.rightCalloutAccessoryView = button
return pinView
}

switch statement gone wrong - swift language

in Obj-c i made a switch statement which i used to move around in my app for iPad using UIsplitviewcontroller
now i want to do the same in swift... i tried for a couple of hours and now the only thing i haven't been able to try is the code because it says some sort of compile error
anyway
here's what i got in Obj-c
-(void)initialSite:(int)viewId {
UIViewController *viewController;
switch (viewId) {
case 0:{
viewController = self.initital;
NSString *star = [NSString stringWithFormat:#"Velkommen til %#'s Bog",[data valueForKey:#"navn"]];
self.navigationItem.title = star;}
break;
case 1:{
viewController = self.startSide;
NSString *start = [NSString stringWithFormat:#"%#'s Bog, start-side",[data valueForKey:#"navn"]];
self.navigationItem.title = start;}
break;
}
[self showChildViewController:viewController];
}
and here's what i come up with so far in swift. still new to this and to understand it is a little hard even tho i have the swift programming language book
here's what i got so far in swift
let viewController = UIViewController()
switch viewController {
case "initial":
let initial : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc0 : UIViewController = initial.instantiateViewControllerWithIdentifier("initial") as UIViewController
self.presentViewController(vc0, animated: true, completion: nil)
let rowData: NSDictionary = self.menuItemArray[indexPath.row] as NSDictionary!
self.navigation.title = rowData["navn"] as? String
case "startSide":
let startSide : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc1 : UIViewController = startSide.instantiateViewControllerWithIdentifier("startSide") as UIViewController
let rowData: NSDictionary = self.manuItemArray[indexPath.row] as NSDictionary!
self.presentViewController(vc1, animated: true, completion: nil)
self.navigation.title = rowData["navn"] as? String
default:
}
the error is : Expected declaration at the line with
let viewController = UIViewcontroller()
Let's start with your Obj-C implementation:
-(void)initialSite:(int)viewId
{
UIViewController *viewController;
switch (viewId)
{
case 0:
{
viewController = self.initital;
NSString *star = [NSString stringWithFormat:#"Velkommen til %#'s Bog",[data valueForKey:#"navn"]];
self.navigationItem.title = star;
}
break;
case 1:
{
viewController = self.startSide;
NSString *start = [NSString stringWithFormat:#"%#'s Bog, start-side",[data valueForKey:#"navn"]];
self.navigationItem.title = start;
}
break;
}
[self showChildViewController:viewController];
}
Now this same snippet in Swift:
func initialSite(viewID:Int)
{
var viewController : UIViewController?
switch (viewID)
{
case 0:
viewController = self.initial
let navn = self.data["navn"] as? String
let star = "Velkommen til \(navn)'s Bog"
self.navigationItem.title = star
case 1:
viewController = self.startSide
let navn = self.data["navn"] as? String
let star = "\(navn)'s Bog, start-side"
self.navigationItem.title = star
default:
viewController = nil
// do nothing
}
self.showChildViewController(viewController)
}
The main thing you have to remember is the difference with var vs let. Typically you will use let to create things unless those things will have their value changed later, which you use var.
The other thing is the use of optionals, with the ? suffix. This is when the value may be nil (unset), otherwise it must contain a value.
Looks like SiLo beat me to it. Anyway I have my solution so I will post it. This is how I would do it:
func initialSite(viewId: Int) -> () {
var viewController: UIViewController?
let dataValue = data["navn"];
var start: String?
switch viewId {
case 1:
viewController = self.initital
start = "Velkommen til \(dataValue)'s Bog"
case 2:
viewController = self.startSide
start = "\(dataValue)'s Bog, start-side"
default:
break;
}
self.navigationItem.title = start!
showChildViewController(viewController!)
}

cocos2d box2d scale sprite -> removechild (how?)

I am little slow in English, please do understand.
Here is my source code:
- (void)createBall:(CGPoint)touchedAt{
CGSize winSize = [CCDirector sharedDirector].winSize;
ball2 = [CCSprite spriteWithFile:#"Ball.png" rect:CGRectMake(0, 0, 54, 54)];
ball2.position = ccp(touchedAt.x,touchedAt.y);
[self addChild:ball2];
b2BodyDef ballBodyDef2;
ballBodyDef2.type = b2_dynamicBody;
ballBodyDef2.position.Set(touchedAt.x/PTM_RATIO, touchedAt.y/PTM_RATIO);
ballBodyDef2.userData = ball2;
b2Body *body2 = _world->CreateBody(&ballBodyDef2);
b2CircleShape circle;
circle.m_radius = 89.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef2;
ballShapeDef2.shape = &circle;
ballShapeDef2.density = 1.0f;
ballShapeDef2.friction = 0.2f;
ballShapeDef2.restitution = 0.8f;
body2->CreateFixture(&ballShapeDef2);
}
-(void)createBall2
{
CGSize winSize = [CCDirector sharedDirector].winSize;
globalSprite = [CCSprite spriteWithFile:#"Ball.png"];
globalSprite.position = ccp(winSize.width/2 + globalSprite.contentSize.width, winSize.height/2);
[self addChild:globalSprite];
b2BodyDef ballBodyDef3;
ballBodyDef3.type = b2_dynamicBody;
ballBodyDef3.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
ballBodyDef3.userData = globalSprite ;
b2Body *body3 = _world->CreateBody(&ballBodyDef3);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef3;
ballShapeDef3.shape = &circle;
ballShapeDef3.density = 1.0f;
ballShapeDef3.friction = 0.2f;
ballShapeDef3.restitution = 0.8f;
body3->CreateFixture(&ballShapeDef3);
}
// initialize your instance here
-(id) init
{
if( (self=[super init])) {
// enable touch
// enable accelerometer
CGSize winSize = [CCDirector sharedDirector].winSize;
self.isAccelerometerEnabled = YES;
self.isTouchEnabled = YES;
// Create sprite and add it to the layer
// Create a world
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
bool doSleep = true;
_world = new b2World(gravity, doSleep);
// Create edges around the entire screen
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = _world->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
// Create ball body and shape
[self schedule:#selector(tick:)];
//[self schedule:#selector(gameLogic:) interval:1.0];
[self createBall2];
}
return self;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
[self createBall:location];
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *ballData = (CCSprite *)b->GetUserData();
ballData.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
I want to
touch -> sprite create(circle) -> sprite scale -> sprite remove
but
- (void)tick:(ccTime) dt <---------- this is simulator turn off!
I want to way
Try this :
world->DestroyBody(sprite);

Resources