generic class Lottie swift - objective-c

I'm new in Swift, I come from objc .. in fact I need to do a classse in Swift "generic" to be called by my controller of the project done in objc. specifically I have to "replace" the few lines of code in the "Lottie" library for the animations of the project. I need to write only my Swift class methods here in obj c .. can you help me? I created this Swift class but I have crashes on the superView, but I'm not sure that's just the problem ...
this is the code I need to replace in Swift:
LOTAnimationView *lottie1Aux = [LOTAnimationView animationNamed:[dict valueForKey:SLIDER_MAP_IMG_KEY]];
lottie1Aux.contentMode = UIViewContentModeScaleToFill;
lottie1Aux.frame = slide.tutorialImageView.bounds;
lottie1Aux.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
lottie1Aux.loopAnimation = YES;
[slide.tutorialImageView addSubview:mySwiftClass];
and the is the Class Swift that I can make for replace and optimize...
import Foundation
import Lottie
import UIKit
#objc
public class myClass: UIViewController {
var alertView: AnimationView!
override public func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
createView()
}
#objc public func createView() {
// Create a red view
let alertWidth: CGFloat = view.bounds.width
let alertHeight: CGFloat = view.bounds.height
let alertViewFrame: CGRect = CGRect(x: 0, y: 0, width: alertWidth, height: alertHeight)
alertView = UIView(frame: alertViewFrame) as! AnimationView
alertView.backgroundColor = UIColor.red
// Create an image view and add it to this view
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: alertWidth, height: alertHeight/2))
imageView.image = UIImage(named: "tour_merchant_pagamento")
alertView.addSubview(imageView)
//view.addSubview(alertView)
alertView = AnimationView(name: "tour_merchant_pagamento")
alertView.contentMode = UIViewContentMode.scaleToFill
alertView.loopMode = .loop
}

I found that you just wanted to convert the above given Objective-C code to latest Swift. I would like to say that its far more easier than before and you can find the guide in Lottie website in iOS section.
Now let's convert your code to Swift.
First download and drag import all Lottie json files to a separate folder inside your Xcode project and name it simple as you wish.
1- You can make it simpler now a days by just creating an outlet for a separate UIView that you wish to assign your animation to inside your desired ViewController class. Don't forget to go to class inspector and select AnimationView in custom class before creating outlet.
Then import Lottie and have a look at below given code example.
import UIKit
import Lottie
class yourClass: UIViewController {
#IBOutlet var yourAnimationView: AnimationView! //the outlet of animationView
override func viewDidLoad() {
createAnimationView()
}
func createAnimationView() {
let yourAnimation = AnimationView(name: "filename") //animation object
yourAnimationView.addSubview(yourAnimation)
yourAnimationView.play()
}
It's simple than you think.

Related

Animating CALayer shadow simultaneously as UITableviewCell height animates

I have a UITableView that I am attempting to expand and collapse using its beginUpdates and endUpdates methods and have a drop shadow displayed as that's happening. In my custom UITableViewCell, I have a layer which I create a shadow for in layoutSubviews:
self.shadowLayer.shadowColor = self.shadowColor.CGColor;
self.shadowLayer.shadowOffset = CGSizeMake(self.shadowOffsetWidth, self.shadowOffsetHeight);
self.shadowLayer.shadowOpacity = self.shadowOpacity;
self.shadowLayer.masksToBounds = NO;
self.shadowLayer.frame = self.layer.bounds;
// this is extremely important for performance when drawing shadows
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.shadowLayer.frame cornerRadius:self.cornerRadius];
self.shadowLayer.shadowPath = shadowPath.CGPath;
I add this layer to the UITableViewCell in viewDidLoad:
self.shadowLayer = [CALayer layer];
self.shadowLayer.backgroundColor = [UIColor whiteColor].CGColor;
[self.layer insertSublayer:self.shadowLayer below:self.contentView.layer];
As I understand it, when I call beginUpdates, an implicit CALayerTransaction is made for the current run loop if none exists. Additionally, layoutSubviews also gets called. The problem here is that the resulting shadow is drawn immediately based on the new size of the UITableViewCell. I really need to shadow to continue to cast in the expected way as the actual layer is animating.
Since my created layer is not a backing CALayer it animates without explicitly specifying a CATransaction, which is expected. But, as I understand it, I really need some way to grab hold of beginUpdates/endUpdates CATransaction and perform the animation in that. How do I do that, if at all?
So I guess you have something like this:
(I turned on “Debug > Slow Animations” in the simulator.) And you don't like the way the shadow jumps to its new size. You want this instead:
You can find my test project in this github repository.
See #horseshoe7's answer for a Swift translation.
It is tricky but not impossible to pick up the animation parameters and add an animation in the table view's animation block. The trickiest part is that you need to update the shadowPath in the layoutSubviews method of the shadowed view itself, or of the shadowed view's immediate superview. In my demo video, that means that the shadowPath needs to be updated by the layoutSubviews method of the green box view or the green box's immediate superview.
I chose to create a ShadowingView class whose only job is to draw and animate the shadow of one of its subviews. Here's the interface:
#interface ShadowingView : UIView
#property (nonatomic, strong) IBOutlet UIView *shadowedView;
#end
To use ShadowingView, I added it to my cell view in my storyboard. Actually it's nested inside a stack view inside the cell. Then I added the green box as a subview of the ShadowingView and connected the shadowedView outlet to the green box.
The ShadowingView implementation has three parts. One is its layoutSubviews method, which sets up the layer shadow properties on its own layer to draw a shadow around its shadowedView subview:
#implementation ShadowingView
- (void)layoutSubviews {
[super layoutSubviews];
CALayer *layer = self.layer;
layer.backgroundColor = nil;
CALayer *shadowedLayer = self.shadowedView.layer;
if (shadowedLayer == nil) {
layer.shadowColor = nil;
return;
}
NSAssert(shadowedLayer.superlayer == layer, #"shadowedView must be my direct subview");
layer.shadowColor = UIColor.blackColor.CGColor;
layer.shadowOffset = CGSizeMake(0, 1);
layer.shadowOpacity = 0.5;
layer.shadowRadius = 3;
layer.masksToBounds = NO;
CGFloat radius = shadowedLayer.cornerRadius;
layer.shadowPath = CGPathCreateWithRoundedRect(shadowedLayer.frame, radius, radius, nil);
}
When this method is run inside an animation block (as is the case when the table view animates a change in the size of a cell), and the method sets shadowPath, Core Animation looks for an “action” to run after updating shadowPath. One of the ways it looks is by sending actionForLayer:forKey: to the layer's delegate, and the delegate is the ShadowingView. So we override actionForLayer:forKey: to provide an action if possible and appropriate. If we can't, we just call super.
It is important to understand that Core Animation asks for the action from inside the shadowPath setter, before actually changing the value of shadowPath.
To provide the action, we make sure the key is #"shadowPath", that there is an existing value for shadowPath, and that there is already an animation on the layer for bounds.size. Why do we look for an existing bounds.size animation? Because that existing animation has the duration and timing function we should use to animate shadowPath. If everything is in order, we grab the existing shadowPath, make a copy of the animation, store them in an action, and return the action:
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event {
if (![event isEqualToString:#"shadowPath"]) { return [super actionForLayer:layer forKey:event]; }
CGPathRef priorPath = layer.shadowPath;
if (priorPath == NULL) { return [super actionForLayer:layer forKey:event]; }
CAAnimation *sizeAnimation = [layer animationForKey:#"bounds.size"];
if (![sizeAnimation isKindOfClass:[CABasicAnimation class]]) { return [super actionForLayer:layer forKey:event]; }
CABasicAnimation *animation = [sizeAnimation copy];
animation.keyPath = #"shadowPath";
ShadowingViewAction *action = [[ShadowingViewAction alloc] init];
action.priorPath = priorPath;
action.pendingAnimation = animation;
return action;
}
#end
What does the action look like? Here's the interface:
#interface ShadowingViewAction : NSObject <CAAction>
#property (nonatomic, strong) CABasicAnimation *pendingAnimation;
#property (nonatomic) CGPathRef priorPath;
#end
The implementation requires a runActionForKey:object:arguments: method. In this method, we update the animation that we created in actionForLayer:forKey: using the saved-away old shadowPath and the new shadowPath, and then we add the animation to the layer.
We also need to manage the retain count of the saved path, because ARC doesn't manage CGPath objects.
#implementation ShadowingViewAction
- (void)runActionForKey:(NSString *)event object:(id)anObject arguments:(NSDictionary *)dict {
if (![anObject isKindOfClass:[CALayer class]] || _pendingAnimation == nil) { return; }
CALayer *layer = anObject;
_pendingAnimation.fromValue = (__bridge id)_priorPath;
_pendingAnimation.toValue = (__bridge id)layer.shadowPath;
[layer addAnimation:_pendingAnimation forKey:#"shadowPath"];
}
- (void)setPriorPath:(CGPathRef)priorPath {
CGPathRetain(priorPath);
CGPathRelease(_priorPath);
_priorPath = priorPath;
}
- (void)dealloc {
CGPathRelease(_priorPath);
}
#end
This is Rob Mayoff's answer written in Swift. Could save someone some time.
Please don't upvote this. Upvote Rob Mayoff's solution. It is awesome, and correct. (Note from mayoff: why not upvote both? 😉)
import UIKit
class AnimatingShadowView: UIView {
struct DropShadowParameters {
var shadowOpacity: Float = 0
var shadowColor: UIColor? = .black
var shadowRadius: CGFloat = 0
var shadowOffset: CGSize = .zero
static let defaultParameters = DropShadowParameters(shadowOpacity: 0.15,
shadowColor: .black,
shadowRadius: 5,
shadowOffset: CGSize(width: 0, height: 1))
}
#IBOutlet weak var contentView: UIView! // no sense in have a shadowView without content!
var shadowParameters: DropShadowParameters = DropShadowParameters.defaultParameters
private func apply(dropShadow: DropShadowParameters) {
let layer = self.layer
layer.shadowColor = dropShadow.shadowColor?.cgColor
layer.shadowOffset = dropShadow.shadowOffset
layer.shadowOpacity = dropShadow.shadowOpacity
layer.shadowRadius = dropShadow.shadowRadius
layer.masksToBounds = false
}
override func layoutSubviews() {
super.layoutSubviews()
let layer = self.layer
layer.backgroundColor = nil
let contentLayer = self.contentView.layer
assert(contentLayer.superlayer == layer, "contentView must be a direct subview of AnimatingShadowView!")
self.apply(dropShadow: self.shadowParameters)
let radius = contentLayer.cornerRadius
layer.shadowPath = UIBezierPath(roundedRect: contentLayer.frame, cornerRadius: radius).cgPath
}
override func action(for layer: CALayer, forKey event: String) -> CAAction? {
guard event == "shadowPath" else {
return super.action(for: layer, forKey: event)
}
guard let priorPath = layer.shadowPath else {
return super.action(for: layer, forKey: event)
}
guard let sizeAnimation = layer.animation(forKey: "bounds.size") as? CABasicAnimation else {
return super.action(for: layer, forKey: event)
}
let animation = sizeAnimation.copy() as! CABasicAnimation
animation.keyPath = "shadowPath"
let action = ShadowingViewAction()
action.priorPath = priorPath
action.pendingAnimation = animation
return action
}
}
private class ShadowingViewAction: NSObject, CAAction {
var pendingAnimation: CABasicAnimation? = nil
var priorPath: CGPath? = nil
// CAAction Protocol
func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable : Any]?) {
guard let layer = anObject as? CALayer, let animation = self.pendingAnimation else {
return
}
animation.fromValue = self.priorPath
animation.toValue = layer.shadowPath
layer.add(animation, forKey: "shadowPath")
}
}
Assuming that you're manually setting your shadowPath, here's a solution inspired by the others here that accomplishes the same thing using less code.
Note that I'm intentionally constructing my own CABasicAnimation rather than copying the bounds.size animation exactly, as in my own tests I found that toggling the copied animation while it was still in progress could cause the animation to snap to it's toValue, rather than transitioning smoothly from its current value.
class ViewWithAutosizedShadowPath: UIView {
override func layoutSubviews() {
super.layoutSubviews()
let oldShadowPath = layer.shadowPath
let newShadowPath = CGPath(rect: bounds, transform: nil)
if let boundsAnimation = layer.animation(forKey: "bounds.size") as? CABasicAnimation {
let shadowPathAnimation = CABasicAnimation(keyPath: "shadowPath")
shadowPathAnimation.duration = boundsAnimation.duration
shadowPathAnimation.timingFunction = boundsAnimation.timingFunction
shadowPathAnimation.fromValue = oldShadowPath
shadowPathAnimation.toValue = newShadowPath
layer.add(shadowPathAnimation, forKey: "shadowPath")
}
layer.shadowPath = newShadowPath
}
}
UITableView is likely not creating a CATransaction, or if it is, it's waiting until after you end the updates. My understanding is that table views just coalesce all changes between those functions and then creates the animations as necessary. You don't have a way to get a handle on the actual animation parameters it's committing, because we don't know when that actually happens. The same thing happens when you animate a content offset change in UIScrollView: the system provides no context about the animation itself, which is frustrating. There is also no way to query the system for current CATransactions.
Probably the best you can do is inspect the animation that UITableView is creating and just mimic the same timing parameters in your own animation. Swizzling add(_:forKey:) on CALayer can allow you to inspect all animations being added. You certainly don't want to actually ship with this, but I often use this technique in debugging to figure out what animations are being added and what their properties are.
I suspect that you're going to have to commit your own shadow layer animations in tableView(_:willDisplayCell:for:row:) for the appropriate cells.

SWIFT: Map - Location issue

I'm new to Swift and write an app to show my locally saved locations on a map. In one ViewController I save the locations
func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!)
{
var latestLocation: AnyObject = locations[locations.count - 1]
latitudeLabel.text = String(format: "%.4f",
latestLocation.coordinate.latitude)
longitudeLabel.text = String(format: "%.4f",
latestLocation.coordinate.longitude)
In an other ViewController I try to show it on the map but since in the second I had to import the MapKit, in the first ViewController appeared an error.
import MapKit
class MapViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
// set initial location in Honolulu
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
I know that the coordinates are no longer supported by the MapKit and instead of AnyObject I should use but I don't know how exactly should I change the locationManager code. :(
Hope someone can help.

PDF Generation Swift

I'm trying to generate a pdf using swift. The following code compiles without error, however, the "xp.pdf" document is never created. Your help is much appreciated.
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func generatePDF(sender: AnyObject) {
let pageSize:CGSize = CGSizeMake (850, 1100)
let fileName: NSString = "xp.pdf"
let path:NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectory: AnyObject = path.objectAtIndex(0)
let pdfPathWithFileName = documentDirectory.stringByAppendingPathComponent(fileName)
generatePDFs(pdfPathWithFileName)
}
func generatePDFs(filePath: String) {
UIGraphicsBeginPDFContextToFile(filePath, CGRectZero, nil)
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 850, 1100), nil)
drawBackground()
UIGraphicsEndPDFContext()
}
func drawBackground () {
let context:CGContextRef = UIGraphicsGetCurrentContext()
let rect:CGRect = CGRectMake(0, 0, 850, 1100)
CGContextSetFillColorWithColor(context, UIColor.greenColor().CGColor)
CGContextFillRect(context, rect)
}
Do you have a pdfkit in the place?
PSPDFKit works pretty well from what I understand. You just need to download it from pspdfkit.com, then drag and drop the PSPDFKit.framework into the "Embedded Binaries" section of your app's target.
You do have to pay for it though, so theres that. I think there is a free trial for it though, so you can try it out and see if thats what you need or want.
For Xcode 7 (swift 2.0) I had to make the following changes to get it to work:
replace:
let pdfPathWithFileName = documentDirectory.stringByAppendingPathComponent(fileName)
with:
let pdfPathWithFileName = documentDirectory.stringByAppendingPathComponent(fileName as String)
and unwrap the UIGraphicsGetCurrentContext():
let context:CGContextRef = UIGraphicsGetCurrentContext()!
and also you can remove:
let pageSize:CGSize = CGSizeMake (850, 1100)
because you never use pageSize

MonoTouch. Rotating background image

I've applied a background image to my ViewController:
ParentViewController.View.BackgroundColor = UIColor.FromPatternImage (image)
Now, when screen orientation gets changed it breakes my entire background thing, because that picture stays as it was. Of course I could just rotate the image in Photoshop and put it in my project, but my humble pride of software engineer revolted.
I've searched through many sources. I've tried objective-c samples. I find only a few in c#. I don't have any time to learn differences between UIKit and Core Graphics. I've tried CGContext.RotateCTM, I've tried to achieve that with CGAffineTransform.MakeRotation. It doesn't work. I just need a simple thing to be done.
Apparently before using RotateCTM or changing CGAffineTransform you have to somehow define the pivotal point.
Please somebody show me a simple example, how it works.
Upd:
This is what I got so far:
var image = new UIImage ("Images/background.jpg");
if (interfaceOrientation == UIInterfaceOrientation.LandscapeLeft) {
CGImage imageRef = image.CGImage;
var width = imageRef.Width;
var height = imageRef.Height;
CGImageAlphaInfo alphaInfo = imageRef.AlphaInfo;
CGColorSpace colorSpaceInfo = CGColorSpace.CreateDeviceRGB ();
CGBitmapContext bitmap =
new CGBitmapContext (IntPtr.Zero, width, height, imageRef.BitsPerComponent, imageRef.BytesPerRow, colorSpaceInfo, alphaInfo);
bitmap.TranslateCTM(0, imageRef.Height);
bitmap.RotateCTM((float)-1.5707f);
bitmap.DrawImage (new Rectangle (0, 0, height, width), imageRef);
image = UIImage.FromImage (bitmap.ToImage());
bitmap = null;
}
ParentViewController.View.BackgroundColor = UIColor.FromPatternImage (image);
and as you can see it ain't no good, though it does rotate:
What am I missing?
Add a UIImageView as subview to your controller's view and load your image into that subview.
You might want to set the ContentMode of the UIImageView to ScaleFit to make it resize.
Set the AutoresizingMask of your UIImageView to FlexibleWidth and FlexibleHeight and you should get the desired result and rotation (as long as your controller override ShouldAutorotateToOrientation()).
var imageView = new UIImageView( UIImage.FromFile( pathToYourImage ) );
EDIT SAMPLE CODE:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Rotate
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow (UIScreen.MainScreen.Bounds);
window.RootViewController = new TestController();
// make the window visible
window.MakeKeyAndVisible ();
return true;
}
}
public class TestController : UIViewController
{
public TestController() : base()
{
}
public override void LoadView ()
{
base.LoadView ();
this.imgView = new UIImageView(UIImage.FromFile("img.png"));
imgView.Frame = new System.Drawing.RectangleF(0, 0, 300, 300);
this.imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
this.imgView.AutoresizingMask = UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleTopMargin | UIViewAutoresizing.FlexibleBottomMargin;
this.View.AddSubview(this.imgView);
}
private UIImageView imgView;
public override void ViewWillAppear (bool animated)
{
this.imgView.Center = new System.Drawing.PointF(this.View.Bounds.Width / 2, this.View.Bounds.Height / 2);
base.ViewWillAppear (animated);
}
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return true;
}
}
}
This might qualify as an inappropriate use of FromPatternImage. In this case the resulting "UIColor" is not a view and does not qualify to receive any rotation events. Therefore you might be able to calculate bounds change, rotate the image, apply the newly calculated bounds, reset the BackgroundColor property all inside WillRotateToInterfaceOrientation(...) but that's pretty convoluted and not even remotely performant.
In my opinion the more sane path is to simply create a UIImageView and place it below everything else in the hierarchy:
var imageView = new UIImageView(UIImage.FromFile("Images/background.png"));
imageView.Frame = new RectangleF(...) // set appropriate frame here
imageView.AutoResizingMask = ...; // set appropriate mask here
ParentViewController.View.AddSubView(imageView);
ParentViewController.View.SendSubviewToBack(imageView);
This allows the system to assume responsibility for stuff it's designed to do, and keep you from having to write expensive rotation code all while achieving the desired effect.
It might be overkill for just an image, but for rotation I've been using this...
https://github.com/escoz/monotouch-controls/blob/master/UICatalog/RotatingViewController.cs

Hide NSWindow title bar

Is there a way to hide the titlebar in an NSWindow? I don't want to have to completely write a new custom window. I can't use NSBorderlessWindowMask because I have a bottom bar on my window, and using NSBorderlessWindowMask makes that disappear. I also tried using setContentBorderThickness:forEdge: with NSMaxYEdge and setting it to 0, that didn't work either.
Any help is appreciated
[yourWindow setStyleMask:NSBorderlessWindowMask];
Starting from OS X 10.10, you can hide title bar.
window1.titlebarAppearsTransparent = true
window1.titleVisibility = .Hidden
Maybe you want to override window style.
window1.styleMask = NSResizableWindowMask
| NSTitledWindowMask
| NSFullSizeContentViewWindowMask
Kind of Welcome screen NSWindow / NSViewController setup (Swift 4.1)
extension NSWindow {
enum Style {
case welcome
}
convenience init(contentRect: CGRect, style: Style) {
switch style {
case .welcome:
let styleMask: NSWindow.StyleMask = [.closable, .titled, .fullSizeContentView]
self.init(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: true)
titlebarAppearsTransparent = true
titleVisibility = .hidden
standardWindowButton(.zoomButton)?.isHidden = true
standardWindowButton(.miniaturizeButton)?.isHidden = true
}
}
}
class WelcomeWindowController: NSWindowController {
private (set) lazy var viewController = WelcomeViewController()
private let contentWindow: NSWindow
init() {
contentWindow = NSWindow(contentRect: CGRect(x: 400, y: 200, width: 800, height: 472), style: .welcome)
super.init(window: contentWindow)
let frameSize = contentWindow.contentRect(forFrameRect: contentWindow.frame).size
viewController.view.setFrameSize(frameSize)
contentWindow.contentViewController = viewController
}
}
class WelcomeViewController: NSViewController {
private lazy var contentView = View()
override func loadView() {
view = contentView
}
init() {
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
contentView.backgroundColor = .white
}
}
class View: NSView {
var backgroundColor: NSColor?
convenience init() {
self.init(frame: NSRect())
}
override func draw(_ dirtyRect: NSRect) {
if let backgroundColor = backgroundColor {
backgroundColor.setFill()
dirtyRect.fill()
} else {
super.draw(dirtyRect)
}
}
}
Result
What happens if you get the superview of the close button? Can you hide that?
// Imagine that 'self' is the NSWindow derived class
NSButton *miniaturizeButton = [self standardWindowButton:NSWindowMiniaturizeButton];
NSView* titleBarView = [miniaturizeButton superview];
[titleBarView setHidden:YES];
The only way I know would be to create a window without a titlebar (see
NSBorderlessWindowMask). Note that you can't (easily) create a window without a
titlebar in IB, so you will have to do a bit of work in code (there are a
couple of different approaches, you can probably figure it out).
A big drawback with using a window without a titlebar is that you're now on the
hook for much more of the standard appearance and behaviour - rounded corners
and such.
I had an experience that when I first set content view of my window and then set the window borderless:
[yourWindow setStyleMask:NSBorderlessWindowMask];
Nothing would appear in my window. So i first set the style mask and after that i've set the content view:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// 1. borderless window
[[self window] setStyleMask: NSBorderlessWindowMask];
// 2. create the master View Controller
self.masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
// 3. Add the view controller to the Window's content view
[self.window.contentView addSubview:self.masterViewController.view];
self.masterViewController.view.frame = ((NSView*)self.window.contentView).bounds;
}
And voila, the content of my window has appeared.
Select Window in storyboard or XIB and tick the red circled option.
You can use WAYInAppStoreWindow available on GitHub which works on Yosemite and Mavericks.
Swift
NSApp.mainWindow?.styleMask = .borderless