How to resize a sublayer in view with in Swift? - view

I have a session with AVfoundation to record a video and take phootos, and this session is necessary add to a view to show this. I add this with this code:
var previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.layerWithSession(self.session) as AVCaptureVideoPreviewLayer
previewLayer.frame = self.imagePreview.bounds
self.imagePreview.layer.addSublayer(previewLayer)
imagePreviw is the UIView.
This is adding correctly, but the session camera only show in a part of the view, how can I show this in all view?
I add picture to show the problem and that I want:

I think the frame is correct but I think you should set the videoGravity like this:
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

Related

How dynamically increase or decrease the number of split view's of a view controller in Mac

I have try to find out programatically add the number of split's of a view controller as per our requirement based upon situation. For example initially we have set a 3 split's view to the view controller page and after some operations we want increase the another split in that view controller. As like that we can able to modify the number of split's count dynamically is my requirement. Please suggest any idea. Thanks in advance.
NSSplitViewController has three methods for manipulating with the NSSplitViewItem array.
AddSplitViewItem
RemoveSplitViewItem
InsertSplitViewItem
Example:
MySplitViewController = new MySplitViewController(); // a NSSplitViewController subclass
var splitViewItem = new NSSplitViewItem();
splitViewItem.ViewController = new RandomViewControllerController();
MySplitViewController.AddSplitViewItem(splitViewItem);
var splitViewItem2 = new NSSplitViewItem();
splitViewItem2.ViewController = new RandomViewControllerController();
MySplitViewController.AddSplitViewItem(splitViewItem2);
PresentViewControllerAsModalWindow(MySplitViewController);
Re: https://developer.apple.com/reference/appkit/nssplitviewcontroller

Getting page dimensions

On navigating to a new page, how do I get the dimensions of the page - the client/layout area only - exclude the action bar if present.
Will I get the same notification when the device orientation changes?
Thanks.
Every view in NativeScript has a method call getMeasuredHeight() as well as getMeasuredWidth(). You can get the page dimensions like this:
var pageHeight, pageWidth;
pageHeight = page.getMeasuredHeight()- page.actionBar.getMeasuredHeight();
pageWidth = page.getMeasuredWidth()- page.actionBar.getMeasuredWidth();

xcode 7.3 reference icon from assets folder for prototype table view cell

In Xcode 7 with swift, I'm trying to use icons from my assets folder to display in the icon slot in a normal prototype tableview cell.
My code compiles and the app runs fine, displaying all the proper row text titles in the table, but all the cells use an icon that I (perhaps stupidly) entered into the attributes inspector for the prototype table cell.
By default, the style=Basic table cell does not have an icon to the left of the Title in the storyboard. BUT... if you add the name of an icon image from the assets folder in the image=MyAssetsIconName, the UI builder automatically adds a UIImageView to the left end of the table row cell. And of course all rows display the image that you selected. Which is what my app currently does.
But I would like to change the icon image for each row, so that the image on any row matches the text rows that I display. So I tried to assign a new image (from the assets folder) to each row cell as it was created. I did the assignment right after I assigned the text title to the cell.
Here is my code, which runs fine (but doesn't display the images that I want).
class TsbReportsCell: UITableViewCell {
#IBOutlet weak var Title: UILabel!
#IBOutlet weak var Detail: UILabel!
#IBOutlet weak var Icon: UIImageView!
...
}
In the table view controller:
In the table view controller class:
// define datasources
var reportnames = [String]()
var reportimages = [String]()
override func viewDidLoad() {
super.viewDidLoad()
reportnames = ["Balance Report",
"Routine Report",
"Low Quality Report"]
reportimages = ["enter.png",
"exterior.png",
"export.png"]
}
override func tableView(tableView:.... {
// all this code works fine
let cell = tableView.dequeueReusableCellWithIdentifier...
let row = indexPath.row
cell.Title.text = reportnames[row]
// here are the lines that seem to have no effect at all
let rowimage = UIImage(named: reportimages[row])
cell.Icon = UIImageView(image: rowimage)
return cell
}
Any ideas what I'm doing wrong? I named an image in the attributes for the table cell row just to get the UI builder to add the imageview placeholder for me. But maybe I'm not allowed to ever override that image, even though I can create an outlet for it.
This seems so simple a problem, but I searched at least 20 posts, the net, the doc, and I still couldn't find anything. Thanks
It's very simple. You are saying:
cell.Icon = UIImageView(image: rowimage)
But that does not put this image view into the interface! It merely assigns it to the cell's property.
Instead, you need to have an image view in the cell and hook an outlet from the cell's Icon property to that image view. As a result, cell.Icon is the image view in the interface. Now you say
cell.Icon.image = rowimage
Man, are you ever fast at answering questions, Matt. I'm sure I'm not the only one who appreciates that.
It's funny how taking a half hour to write up a decent question for this site makes you start thinking about other things to try. I took a seg fault on one of my tries, and was poking around in the error messages. From them, I got the idea that an ImageView was a structure that had an "image" field in it (or something like that), so I tried some UIImageView x UIImage crosses to see what would happen.
Sure enough, I was trying to assign an ImageView to an Image (I think; I could still be wrong). Here's the code line that worked for me.
cell.Icon.image = UIImage(named: reportimages[row])
So you can see I'm assigning an image to an image here, which works properly. AND... it must be right, because it's the same code as Matt's!! :-)

Add new artboard with Sketch Plugin

I'm trying to build my first Sketch Plugin that starts by adding a new Artboard to the page. Sketch plugins use JSTalk, and in the Bohemian Coding documentation it states that Artboards are a type of layer, so one would think you could use addLayerOfType to insert a new artboard.
This is what I'm doing to try and create a new Artboard, using the JS Syntax:
var page = doc.currentPage()
var artboard = page.addLayerOfType("artboard")
However if I log() the output of artboard I get (null). I've also tried it with Cocoa syntax:
var page = [doc currentPage]
var artboard = [page addLayerOfType:"artboard"]
No luck. Anyone know how I can do this?
Referencing the MSPage documentation, it look like you need to use the addLayer method.
artboards
Returns a readonly array of all artboards on the page. If you want to
add a new artboard to a page, use the addLayer method.
addLayer
Adds an MSLayer to the page. For example, if you want to add an
800x600 artboard to the current page, you'd do this:
var artboard = [MSArtboardGroup new]
var frame = [artboard frame]
[frame setX:0]
[frame setY:0]
[frame setWidth:800]
[frame setHeight:600]
[[doc currentPage] addLayer:artboard]

UICollectionView effective drag and drop

I am currently trying to implement the UITableView reordering behavior using UICollectionView.
Let's call a UItableView TV and a UICollectionView CV (to clarify the following explanation)
I am basically trying to reproduce the drag&drop of the TV, but I am not using the edit mode, the cell is ready to be moved as soon as the long press gesture is triggered. It works prefectly, I am using the move method of the CV, everything is fine.
I update the contentOffset property of the CV to handle the scroll when the user is dragging a cell. When a user goes to a particular rect at the top and the bottom, I update the contentOffset and the CV scroll. The problem is when the user stop moving it's finger, the gesture doesn't send any update which makes the scroll stop and start again as soon as the user moves his finger.
This behavior is definitely not natural, I would prefer continu to scroll until the user release the CV as it is the case in the TV. The TV drag&drop experience is awesome and I really want to reproduce the same feeling. Does anyone know how they manage the scroll in TV during reordering ?
I tried using a timer to trigger a scroll action repeatedly as long as the gesture position is in the right spot, the scroll was awful and not very productive (very slow and jumpy).
I also tried using GCD to listen the gesture position in another thread but the result is even worst.
I ran out of idea about that, so if someone has the answer I would marry him!
Here is the implementation of the longPress method:
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGPoint gesturePosition = [sender locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:gesturePosition];
if (sender.state == UIGestureRecognizerStateBegan)
{
layout.selectedItem = selectedIndexPath;
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
}
else if (sender.state == UIGestureRecognizerStateChanged)
{
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
[self swapCellAtPoint:gesturePosition];
[self manageScrollWithReferencePoint:gesturePosition];
}
else
{
[self.collectionView performBatchUpdates:^
{
layout.selectedItem = nil;
layout.gesturePoint = CGPointZero; // Setting gesturePoint invalidate layout
} completion:^(BOOL completion){[self.collectionView reloadData];}];
}
}
To make the CV scroll, I am using that method:
- (void)manageScrollWithReferencePoint:(CGPoint)gesturePoint
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGFloat topScrollLimit = self.collectionView.contentOffset.y+layout.itemSize.height/2+SCROLL_BORDER;
CGFloat bottomScrollLimit = self.collectionView.contentOffset.y+self.collectionView.frame.size.height-layout.itemSize.height/2-SCROLL_BORDER;
CGPoint contentOffset = self.collectionView.contentOffset;
if (gesturePoint.y < topScrollLimit && gesturePoint.y - layout.itemSize.height/2 - SCROLL_BORDER > 0)
contentOffset.y -= SCROLL_STEP;
else if (gesturePoint.y > bottomScrollLimit &&
gesturePoint.y + layout.itemSize.height/2 + SCROLL_BORDER < self.collectionView.contentSize.height)
contentOffset.y += SCROLL_STEP;
[self.collectionView setContentOffset:contentOffset];
}
This might help
https://github.com/lxcid/LXReorderableCollectionViewFlowLayout
This is extends the UICollectionView to allow each of the UICollectionViewCells to be rearranged manually by the user with a long touch (aka touch-and-hold). The user can drag the Cell to any other position in the collection and the other cells will reorder automatically. Thanks go to lxcid for this.
Here is an alternative:
The differences between DraggableCollectionView and LXReorderableCollectionViewFlowLayout are:
The data source is only changed once. This means that while the user is dragging an item the cells are re-positioned without modifying the data source.
It's written in such a way that makes it possible to use with custom layouts.
It uses a CADisplayLink for smooth scrolling and animation.
Animations are canceled less frequently while dragging. It feels more "natural".
The protocol extends UICollectionViewDataSource with methods similar to UITableViewDataSource.
It's a work in progress. Multiple sections are now supported.
To use it with a custom layout see DraggableCollectionViewFlowLayout. Most of the logic exists in LSCollectionViewLayoutHelper. There is also an example in CircleLayoutDemo showing how to make Apple's CircleLayout example from WWDC 2012 work.
As of iOS 9, UICollectionView now supports reordering.
For UICollectionViewControllers, just override collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
For UICollectionViews, you'll have to handle the gestures yourself in addition to implementing the UICollectionViewDataSource method above.
Here's the code from the source:
private var longPressGesture: UILongPressGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
longPressGesture = UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")
self.collectionView.addGestureRecognizer(longPressGesture)
}
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case UIGestureRecognizerState.Began:
guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
case UIGestureRecognizerState.Changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
case UIGestureRecognizerState.Ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
Sources:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/#//apple_ref/doc/uid/TP40012177-CH1-SW67
http://nshint.io/blog/2015/07/16/uicollectionviews-now-have-easy-reordering/
If you want to experiment rolling out your own, I just wrote a Swift based tutorial you can look. I tried to build the most basic of cases so as to be easier to follow this.
Here is another approach:
Key difference is that this solution does not require a "ghost" or "dummy" cell to provide the drag and drop functionality. It simply uses the cell itself. Animations are in line with UITableView. It works by adjusting the collection view layout's private datasource while moving around. Once you let go, it will tell your controller that you can commit the change to your own datasource.
I believe it's a bit simpler to work with for most use cases. Still a work in progress, but yet another way to accomplish this. Most should find this pretty easy to incorporate into their own custom UICollectionViewLayouts.

Resources