Change WebView position Cocoa - cocoa

I'm quite a newbie to Cocoa & Mac programming. I have a WebView and I want to move it. Is there a way to change the coordinates of the WebView?
EDIT: Some relevant code:
NistractAppDelegate.m
#import "NistractAppDelegate.h"
#implementation NistractAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[window setAlphaValue:0];
[window setBackgroundColor:[NSColor colorWithCalibratedRed:0.125490196078431 green:0.125490196078431 blue:0.125490196078431 alpha:1]];
[mainWebView setBackgroundColor:[NSColor colorWithCalibratedRed:0.125490196078431 green:0.125490196078431 blue:0.125490196078431 alpha:1]];
[[mainWebView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
mainWebView.frame = NSMakeRect(mainWebView.frame.origin.x + 10, mainWebView.frame.origin.y, mainWebView.frame.size.width, mainWebView.frame.size.height);
[window makeKeyAndOrderFront:self];
[[window animator] setAlphaValue:1];
}
#end
NistractAppDelegate.h
#import <Cocoa/Cocoa.h>
#interface NistractAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
IBOutlet NSView *mainView;
IBOutlet id mainWebView;
}
#property (assign) IBOutlet NSWindow *window;
#end

If you just want to move the entire webview you need set it's frame.
WebView.frame = NSMakeRect(x,y,width,height);
Eg if you want to just shift it left by ten pixels:
WebView.frame = NSMakeRect(WebView.frame.origin.x + 10, WebView.frame.origin.y, WebView.frame.size.width, WebView.frame.size.height);
When in doubt always you look in the documentation, which you can do from within side XCode, by selecting some text and right clicking then selecting Find Text In Documentation
Or use Google by searching "{Class name} class reference" Eg "nsview class reference"

Related

Making OpenGL coexist with Core Animation on macOS

Is it possible for a layer-backed NSView to correctly do OpenGL rendering in drawRect:, or is it necessary to use NSOpenGLLayer/CAOpenGLLayer? Until recently, I haven't needed to worry about that, I just used a non-layer-backed view. But as stated in the AppKit release notes for 10.14:
Windows in apps linked against the macOS 10.14 SDK are displayed using Core Animation when the app is running in macOS 10.14.
To show how this breaks my rendering, I put together a sample app, with code shown below. If the project is run on an OS before Mojave, or is built using an SDK before 10.14, then the view shows solid red that stays that way if the window is resized. But if the project is build using the 10.14 SDK and run under macOS 10.14, then as the window is resized, the view flickers madly, and when you stop resizing, the view may or may not show anything.
Here's the project folder. Also, here is the app, built under High Sierra but with two instances of the view, one marked layer-backed in the nib.
-- AppDelegate.h --
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (strong) NSOpenGLPixelFormat* pixelFormat;
#end
-- AppDelegate.m --
#import "AppDelegate.h"
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#end
#implementation AppDelegate
- (instancetype) init
{
self = [super init];
if (self != nil)
{
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize,
32,
0
};
_pixelFormat = [[NSOpenGLPixelFormat alloc]
initWithAttributes: attribs];
NSLog(#"Got pixel format %#", _pixelFormat);
}
return self;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self.window makeKeyAndOrderFront: self];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
}
#end
-- MyGLView.h --
#import <Cocoa/Cocoa.h>
#class AppDelegate;
#interface MyGLView : NSView
#property (weak) IBOutlet AppDelegate* appDelegate;
#end
-- MyGLView.m --
#import "MyGLView.h"
#import "AppDelegate.h"
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#interface MyGLView ()
#property (strong) NSOpenGLContext* openGLContext;
#end
#implementation MyGLView
- (void) awakeFromNib
{
self.openGLContext = [[NSOpenGLContext alloc]
initWithFormat: self.appDelegate.pixelFormat shareContext: nil];
self.openGLContext.view = self;
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(resized:)
name: NSViewFrameDidChangeNotification
object: self];
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
- (void) resized: (NSNotification*) note
{
[self.openGLContext update];
}
- (void) drawRect:(NSRect) dirtyRect
{
[self.openGLContext makeCurrentContext];
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
[self.openGLContext flushBuffer];
}
#end
Update:
It's looking as if what I wanted to do can't be done. So my choices are to use NSOpenGLView, which uses a private class _NSOpenGLViewBackingLayer for its layer, or use NSOpenGLLayer.
I find NSOpenGLLayer confusing because although it seems to be rendering on screen, it's actually rendering to an FBO. And even if you start with a pixel format that supports double-buffering, you're really doing single-buffered rendering. In contrast, NSOpenGLView appears to render to the main frame buffer, double-buffered if you like.

Range or index out of bounds (App is crashing)

I have an app with ads banner (inner-active) in every view controller (4 views) and i keep getting this error after 2-3-4 minutes that my app is running:
'NSRangeException', reason: '*** -[__NSCFString substringToIndex:]: Range or index out of bounds'
My app is crashing & i can't find the solution for that, but i know for sure that is something with my AD banner issue cau's when i comment the ad banner code everything works great. i can assume that it happens when new request is loading on the banner.
This is the code i'm using for the AD banner:
.h file:
#property (nonatomic, retain) UIView *adBanner;
.m file:
Did synthesize & import for what i need and after that:
- (void)viewWillAppear:(BOOL)animated
{
CGRect frame = CGRectMake(0, 430, 320, 50);
self.adBanner = [[UIView alloc] initWithFrame:frame];
[self.view addSubview:self.adBanner];
// Display ad
if (![InneractiveAd DisplayAd:#"iOS_Test" withType:IaAdType_Banner withRoot:adBanner withReload:60 withParams:optionalParams])
{
adBanner.hidden = YES;
}
}
This is my AppDelegate (don't know why but maybe it something with that too?):
.h file:
#import <UIKit/UIKit.h>
#class RootViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) RootViewController *rootViewController;
#end
.m file:
#import "AppDelegate.h"
#import "RootViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize rootViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:NULL];
[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];
return YES;
}
I realy don't understand what it could be and how it related to NSCFString :\
Thanks.
Not sure if you got an answer to this but I was getting it with this line of code when there was no internet connection.
NSString *value = [serverOutput substringWithRange:NSMakeRange(2, [serverOutput length] - 2 * 2)];
I had to protect it with a check to the internet connection and an if then statement

Switching between two NSWindows

I am making a simple mac app in which i want to switch windows.
I have two NSWindowController class MainWindow and DetailWindow
I am using this code :
MainWindow class:
//MainWindow.h
#class DetailWindow;
#interface MainWindow : NSWindowController{
IBOutlet NSButton *btn1;
DetailWindow *detailwindow;
}
#property (nonatomic, retain) IBOutlet NSButton *btn1;
- (IBAction)btn1Event:(id)sender;
//MainWindow.m
#implementation MainWindow
#synthesize btn1;
- (IBAction)btn1Event:(id)sender {
if (!detailwindow) {
detailwindow = [[DetailWindow alloc] initWithWindowNibName:#"DetailWindow"];
}
[detailwindow showWindow:self];
}
#end
DetailWindow Class:
//DetailWindow.h
#class MainWindow;
#interface DetailWindow : NSWindowController{
IBOutlet NSButton *backbtn;
MainWindow *mainwindow;
}
#property (nonatomic, retain) IBOutlet NSButton *backbtn;
- (IBAction)back:(id)sender;
//DetailWindow.m
#implementation DetailWindow
#synthesize backbtn;
- (IBAction)back:(id)sender {
if (!mainwindow) {
mainwindow = [[MainWindow alloc] initWithWindowNibName:#"MainWindow"];
}
[mainwindow showWindow:self];
}
#end
Now the problem is when i click backbtn on DetaiWindow it will open a new MainWindow.
So i have two MainWindow on screen.
I want just main window at front when i click backbtn.
Any help??
Thank you..!!
Your basic problem is that each window is assuming that it is its own job to create the other. Each has an ivar for the other, but there's no external access to it -- via a property or being an IBOutlet or anything else -- so it always starts out as nil, and a new copy gets created instead of reusing the old one.
There are any number of ways to get around this. Probably the easiest would be to create both windows in Interface Builder and link them up there, having made the ivars IBOutlet. Then you know you never have to create them in code at all.
However, purely on the basis of inertia, here's an alternative that sticks closer to what you've got already. Note that I've assumed for simplicity that mainWindow always exists first. If not, you'll have to duplicate the process the other way around.
//MainWindow.h
#class DetailWindow;
#interface MainWindow : NSWindowController
{
IBOutlet NSButton *btn1;
DetailWindow *detailwindow;
}
#property (nonatomic, retain) NSButton *btn1;
- (IBAction)btn1Event:(id)sender;
//MainWindow.m
#implementation MainWindow
#synthesize btn1;
- (IBAction)btn1Event:(id)sender
{
if (!detailwindow)
{
detailwindow = [[DetailWindow alloc] initWithWindowNibName:#"DetailWindow"];
// having created the other window, give it a reference back to this one
detailWindow.mainWindow = self;
}
[detailwindow showWindow:self];
}
#end
//DetailWindow.h
#class MainWindow;
#interface DetailWindow : NSWindowController
{
IBOutlet NSButton *backbtn;
MainWindow *mainwindow;
}
#property (nonatomic, retain) NSButton *backbtn;
// allow the main window to be set from outside
#property (nonatomic, retain) MainWindow *mainWindow;
- (IBAction)back:(id)sender;
//DetailWindow.m
#implementation DetailWindow
#synthesize backbtn;
#synthesize mainWindow;
- (IBAction)back:(id)sender
{
// no window creation on the way back
NSAssert(mainWindow, "mainWindow not set!");
[mainwindow showWindow:self];
}
#end
Untested, so usual caveats apply.
You have to call orderFront: method with self object on main window.
To do this you must find a reference to the main window. A way to do this is:
[NSApp mainWindow];
This call will return you a pointer to your main window (If you did something incorrect, you could have to cycle through the [NSApp windows] array in order to search for your main window).
When you have found the window, send it a orderFront message, by doing (supposing the code above returns the correct window, as explained before).
[[NSApp mainWindow] orderFront:self];
and the window should magically order front.

How to make a program load an web image and show it on a Custom View?

Well, I'm learning how to program on a mac, and I'm tired of searching the for answers, can you guys explain me what I did wrong on my program.
First, I dragged 2 buttons on my window (Load Image, and Unload). Then, I dragged a custom view item and here`s what I did with the Test_Loading_ImagesAppDelegate.h:
#import <Cocoa/Cocoa.h>
#interface Test_Loading_ImagesAppDelegate : NSView {
NSWindow *window;
IBOutlet NSView *mypicture;
}
- (IBAction)LoadImage: (id)sender;
- (IBAction)Unload: (id)sender;
#property (assign) IBOutlet NSWindow *window;
#end
After that, I linked up things on Interface Builder normally and made the Test_Loading_ImagesAppDelegate.m:
#import "Test_Loading_ImagesAppDelegate.h"
#implementation Test_Loading_ImagesAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
-(IBAction)LoadImage: (id) sender {
NSURL *myurl;
NSImage *image;
NSData *myurldata;
myurl = [NSURL URLWithString:#"http://....jpg"];
myurldata = [NSData dataWithContentsOfURL:myurl];
image = [NSImage initWithData:myurldata];
[mypicture setImage: image];
}
-(IBAction)Unload: (id) sender {
//Well, still thinking how I'm going to do this, and I would like to make another question: If I dealloc the View or something else the image will disappear?
}
#end
Thanks in advance.
Well, after coming here again I've found this http://www.markj.net/iphone-asynchronous-table-image/ it's for iPhone but can be adapted to OS X easily. Thanks.

COCOA: NSStatusitem icon disappearing on launching external code

I am a .Net developer that needs to port a small program over to Mac OS X. I have this mostly done (partly thanks to people on this site, thanks!) but have a bug that maybe people I can get help with.
I am creating a tool that sits in the status bar, that when clicked opens a window with several links or buttons. When the links or buttons are clicked they either open a website or external program. The problem is that the icon in the status bar disappears as I launch one of these external commands. Even more interesting is that the space on the status bar where the icon should be still responds; meaning that if I click on the area (even without the visible icon) it still runs the code and opens the window.
Here is the current code:
tray.m
#import "tray.h"
#import "MyView.h"
#implementation Tray
-(void) awakeFromNib{
NSBundle *bundle = [NSBundle mainBundle];
statusItem = [[NSImage alloc] initWithContentsofFile:[bundle pathForResource:"#icon" ofType:#"png"]];
MyView *view = [MyView new];
[statusItem setImage:statusImage];
view.image = statusImage;
[statusitem setView:view];
[statusitem setToolTip:#"Tray App"];
[view setTarget:self];
[view setAction:#selector(openWindow)];
}
-(IBAction)openWindow:(id)sender{
[trayWin makeKeyAndOrderFront:nil];
}
-(IBAction)openActMon:(id)sender {
(void)system("open '\/Applications/Utilities/Activity Monitor.app'");
}
tray.h
#import "MyView.h"
#interface Tray : NSObject {
NSStatusItem *statusItem;
NSImage *statusImage;
IBOutlet NSWindow * trayWin;
IBOutlet NSButton *ActMon;
void *openWindow;
}
#property (retain,nonatomic) NSStatusItem *statusItem;
-(IBAction)ActMon:(id)sender;
#end
MyView.h
#interface MyView : NSControl {
NSImage *image;
id target;
SEL action;
}
#property (retain)NSImage *image;
#property (assign) id target;
#property (assign) SEL action;
#end
MyView.m
#import "MyView.h"
#implementation MyView;
#synthethize image, target, action;
-(void)mousemouseUP:(NSEvent *)event{
[NSApp sendAction:selfself.action to:self.target from:self];
}
-(void)dealloc {
self.image = nil;
[super dealloc];
}
-(void)drawRect:(NSRect)rect {
[self.image drawInRect:CGRectMake(0,0,18,18) fromRect:NSZeroRect operation:NSCompositeSourceOver];
}
#end
}
The openActMon is run when the image/button is clicked, the image is located in the trayWin Window that is opened when the icon is clicked. At this point, Activity monitor successfully launches, but the icon in the StatusBar disappears.
I have tried putting a [super setNeedsDisplay:YES] in the openActMon, but that didn't help. And I added [view setNeedsDisplay:YES] in the openActMon and it responded undeclared.
I have given all of this code because, as I said, I am not a Objective-C coder, but .Net who just needs to port something small over. Hoping that this will be helpful to others in the future. Alot of this I have hodgepodged together from different forums and sites or have gotten from some help on StackOverflow. I am hoping someone can help.
Thanks in advance!
In awakeFromNib add:
[statusitem retain];
In awakeFromNib, you are allocating the NSImage into statusItem. I think you mean to allocate it into statusImage.

Resources