Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Selection is Not a Type that Can Be Renamed Xcode 7

Trying to rename a class by selecting the class name (ViewController) after @interface:

@interface ViewController : UIViewController

Right clicking, selecting Refactor -> Rename results in the following error alert window:

enter image description here

This worked just fine in Xcode 6, is this some sort of regression? I tried this solution for Xcode 4 to no avail. Anyone know of any work arounds?

like image 486
Stunner Avatar asked Sep 23 '15 01:09

Stunner


2 Answers

Yes, refactoring is badly broken in Xcode 7.

I have found similar problems when trying to rename properties, methods and classes. Yesterday I downloaded 7.1.1 with a hope that there might be some improvements but none so far.

I did some testing in a sample single view project in Objective-C on Xcode 7.1.1 and found the following:

  1. If you try to rename a property that has IBOutlet keyword, it will fail;
  2. If you try to rename another property which is not IBOutlet, but above it's declaration you have any property that is IBOutlet, rename will fail;
  3. If you try to rename a method which is declared below IBOutlet property and do it right clicking the method in .h file, rename will fail;
  4. If you try to rename a class that #imports a class that has some IBOutlet declarations in the header file, rename will fail (highlighted since this is the case, that original question is about).

Luckily I also found some workarounds:

  1. If you move the declaration of your property above IBOutlet declarations, rename will succeed;
  2. If you need to rename IBOutlet - you can move it above all other IBOutlets and remove the IBOutlet keyword of it before renaming it. Rename will succeed (and will also rename it within Storyboard), then you can add the IBOutlet keyword back;
  3. If you move declaration of your method above any IBOutlet properties rename will succeed from .h file, but alternatively it also seems to work if you try to rename it when selecting in a .m file (the latter case works even if method is declared in .h file below IBoutlet properties);
  4. When renaming class that imports another class with IBOutlets, you can do the following - move the IBOutlets of the other class from .h file to .m file. Then rename works. Alternatively - remove all IBOutlet keywords before the rename, and then add them back after it.

Note: When I say that rename succeeds, I mean - it won't show you "The selection is not a type that can be renamed". However it still does not work smoothly most of the time:

  1. It does not show the changes to be made in files, like it used to do;
  2. It may complain about the fact that files have been modified by another application while Xcode has unsaved changes. As I have found, usually you need to choose "Keep Xcode Version";
  3. It may fail to rename the property in all of the files it has been used. This is the most important, which in some cases make all the workarounds useless. Specifically I've seen it when renaming IBOutlet properties with method I've described above.

Hope it helps :)

like image 50
Andris Zalitis Avatar answered Oct 19 '22 07:10

Andris Zalitis


One way to workaround this issue until it is corrected in Xcode is add a forward declaration to the header file (in a separate line above the @interface line). Like this:

@class ClassName

After it is added, do the rename on this, instead of on the @interface line. You can remove the forward declaration after renaming

like image 24
MSimic Avatar answered Oct 19 '22 07:10

MSimic